Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 May 2016 06:42:14 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r300574 - head/sys/dev/hyperv/vmbus
Message-ID:  <201605240642.u4O6gE47066579@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Tue May 24 06:42:14 2016
New Revision: 300574
URL: https://svnweb.freebsd.org/changeset/base/300574

Log:
  hyperv/vmbus: Factor out functions for vmbus interrupt set/teardown
  
  This paves way for further cleanup and fix.
  
  MFC after:	1 week
  Sponsored by:	Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D6505

Modified:
  head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Tue May 24 06:10:21 2016	(r300573)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Tue May 24 06:42:14 2016	(r300574)
@@ -72,6 +72,8 @@ static int vmbus_inited;
 
 static char *vmbus_ids[] = { "VMBUS", NULL };
 
+extern inthand_t IDTVEC(hv_vmbus_callback);
+
 static void
 vmbus_msg_task(void *xsc, int pending __unused)
 {
@@ -361,6 +363,82 @@ vmbus_dma_free(struct vmbus_softc *sc)
 }
 
 static int
+vmbus_intr_setup(struct vmbus_softc *sc)
+{
+	int cpu;
+
+	/*
+	 * Find a free IDT vector for vmbus messages/events.
+	 */
+	sc->vmbus_idtvec = lapic_ipi_alloc(IDTVEC(hv_vmbus_callback));
+	if (sc->vmbus_idtvec < 0) {
+		device_printf(sc->vmbus_dev, "cannot find free IDT vector\n");
+		return ENXIO;
+	}
+	if(bootverbose) {
+		device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n",
+		    sc->vmbus_idtvec);
+	}
+
+	CPU_FOREACH(cpu) {
+		char buf[MAXCOMLEN + 1];
+
+		snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
+		intrcnt_add(buf, VMBUS_PCPU_PTR(sc, intr_cnt, cpu));
+	}
+
+	/*
+	 * Per cpu setup.
+	 */
+	CPU_FOREACH(cpu) {
+		cpuset_t cpu_mask;
+
+		/*
+		 * Setup taskqueue to handle events
+		 */
+		hv_vmbus_g_context.hv_event_queue[cpu] =
+		    taskqueue_create_fast("hyperv event", M_WAITOK,
+		    taskqueue_thread_enqueue,
+		    &hv_vmbus_g_context.hv_event_queue[cpu]);
+		CPU_SETOF(cpu, &cpu_mask);
+		taskqueue_start_threads_cpuset(
+		    &hv_vmbus_g_context.hv_event_queue[cpu], 1, PI_NET,
+		    &cpu_mask, "hvevent%d", cpu);
+
+		/*
+		 * Setup per-cpu tasks and taskqueues to handle msg.
+		 */
+		hv_vmbus_g_context.hv_msg_tq[cpu] = taskqueue_create_fast(
+		    "hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
+		    &hv_vmbus_g_context.hv_msg_tq[cpu]);
+		CPU_SETOF(cpu, &cpu_mask);
+		taskqueue_start_threads_cpuset(
+		    &hv_vmbus_g_context.hv_msg_tq[cpu], 1, PI_NET,
+		    &cpu_mask, "hvmsg%d", cpu);
+		TASK_INIT(&hv_vmbus_g_context.hv_msg_task[cpu], 0,
+		    vmbus_msg_task, sc);
+	}
+	return 0;
+}
+
+static void
+vmbus_intr_teardown(struct vmbus_softc *sc)
+{
+	int cpu;
+
+	CPU_FOREACH(cpu) {
+		if (hv_vmbus_g_context.hv_event_queue[cpu] != NULL) {
+			taskqueue_free(hv_vmbus_g_context.hv_event_queue[cpu]);
+			hv_vmbus_g_context.hv_event_queue[cpu] = NULL;
+		}
+	}
+	if (sc->vmbus_idtvec >= 0) {
+		lapic_ipi_free(sc->vmbus_idtvec);
+		sc->vmbus_idtvec = -1;
+	}
+}
+
+static int
 vmbus_read_ivar(
 	device_t	dev,
 	device_t	child,
@@ -504,8 +582,6 @@ vmbus_probe(device_t dev)
 	return (BUS_PROBE_DEFAULT);
 }
 
-extern inthand_t IDTVEC(hv_vmbus_callback);
-
 /**
  * @brief Main vmbus driver initialization routine.
  *
@@ -522,9 +598,7 @@ static int
 vmbus_bus_init(void)
 {
 	struct vmbus_softc *sc;
-	int ret, cpu;
-	char buf[MAXCOMLEN + 1];
-	cpuset_t cpu_mask;
+	int ret;
 
 	if (vmbus_inited)
 		return (0);
@@ -533,56 +607,14 @@ vmbus_bus_init(void)
 	sc = vmbus_get_softc();
 
 	/*
-	 * Find a free IDT vector for vmbus messages/events.
+	 * Setup interrupt.
 	 */
-	sc->vmbus_idtvec = lapic_ipi_alloc(IDTVEC(hv_vmbus_callback));
-	if (sc->vmbus_idtvec < 0) {
-		device_printf(sc->vmbus_dev, "cannot find free IDT vector\n");
-		ret = ENXIO;
+	ret = vmbus_intr_setup(sc);
+	if (ret != 0)
 		goto cleanup;
-	}
-	if(bootverbose) {
-		device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n",
-		    sc->vmbus_idtvec);
-	}
-
-	CPU_FOREACH(cpu) {
-		snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
-		intrcnt_add(buf, VMBUS_PCPU_PTR(sc, intr_cnt, cpu));
-	}
 
 	/*
-	 * Per cpu setup.
-	 */
-	CPU_FOREACH(cpu) {
-		/*
-		 * Setup taskqueue to handle events
-		 */
-		hv_vmbus_g_context.hv_event_queue[cpu] =
-		    taskqueue_create_fast("hyperv event", M_WAITOK,
-		    taskqueue_thread_enqueue,
-		    &hv_vmbus_g_context.hv_event_queue[cpu]);
-		CPU_SETOF(cpu, &cpu_mask);
-		taskqueue_start_threads_cpuset(
-		    &hv_vmbus_g_context.hv_event_queue[cpu], 1, PI_NET,
-		    &cpu_mask, "hvevent%d", cpu);
-
-		/*
-		 * Setup per-cpu tasks and taskqueues to handle msg.
-		 */
-		hv_vmbus_g_context.hv_msg_tq[cpu] = taskqueue_create_fast(
-		    "hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
-		    &hv_vmbus_g_context.hv_msg_tq[cpu]);
-		CPU_SETOF(cpu, &cpu_mask);
-		taskqueue_start_threads_cpuset(
-		    &hv_vmbus_g_context.hv_msg_tq[cpu], 1, PI_NET,
-		    &cpu_mask, "hvmsg%d", cpu);
-		TASK_INIT(&hv_vmbus_g_context.hv_msg_task[cpu], 0,
-		    vmbus_msg_task, sc);
-	}
-
-	/*
-	 * Allocate vmbus DMA stuffs.
+	 * Allocate DMA stuffs.
 	 */
 	vmbus_dma_alloc(sc);
 
@@ -597,7 +629,7 @@ vmbus_bus_init(void)
 	ret = hv_vmbus_connect();
 
 	if (ret != 0)
-		goto cleanup1;
+		goto cleanup;
 
 	if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 ||
 	    hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)
@@ -613,22 +645,10 @@ vmbus_bus_init(void)
 
 	return (ret);
 
-cleanup1:
+cleanup:
 	vmbus_dma_free(sc);
+	vmbus_intr_teardown(sc);
 
-	/*
-	 * remove swi and vmbus callback vector;
-	 */
-	CPU_FOREACH(cpu) {
-		if (hv_vmbus_g_context.hv_event_queue[cpu] != NULL) {
-			taskqueue_free(hv_vmbus_g_context.hv_event_queue[cpu]);
-			hv_vmbus_g_context.hv_event_queue[cpu] = NULL;
-		}
-	}
-
-	lapic_ipi_free(sc->vmbus_idtvec);
-
-	cleanup:
 	return (ret);
 }
 
@@ -642,6 +662,7 @@ vmbus_attach(device_t dev)
 {
 	vmbus_sc = device_get_softc(dev);
 	vmbus_sc->vmbus_dev = dev;
+	vmbus_sc->vmbus_idtvec = -1;
 
 	/*
 	 * Event processing logic will be configured:
@@ -687,7 +708,6 @@ static int
 vmbus_detach(device_t dev)
 {
 	struct vmbus_softc *sc = device_get_softc(dev);
-	int i;
 
 	hv_vmbus_release_unattached_channels();
 	hv_vmbus_disconnect();
@@ -695,16 +715,7 @@ vmbus_detach(device_t dev)
 	smp_rendezvous(NULL, vmbus_synic_teardown, NULL, NULL);
 
 	vmbus_dma_free(sc);
-
-	/* remove swi */
-	CPU_FOREACH(i) {
-		if (hv_vmbus_g_context.hv_event_queue[i] != NULL) {
-			taskqueue_free(hv_vmbus_g_context.hv_event_queue[i]);
-			hv_vmbus_g_context.hv_event_queue[i] = NULL;
-		}
-	}
-
-	lapic_ipi_free(sc->vmbus_idtvec);
+	vmbus_intr_teardown(sc);
 
 	return (0);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605240642.u4O6gE47066579>