Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Jun 2016 05:51:57 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r302118 - stable/10/sys/dev/hyperv/vmbus
Message-ID:  <201606230551.u5N5pvrx089248@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Thu Jun 23 05:51:57 2016
New Revision: 302118
URL: https://svnweb.freebsd.org/changeset/base/302118

Log:
  MFC 300572
  
      hyperv/vmbus: Use busdma(9) for messages and event flags
  
      And
      - Move message and event flags to vmbus_softc per-cpu data.
      - Get rid of hv_setup_arg, which serves no purpose now.
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D6502

Modified:
  stable/10/sys/dev/hyperv/vmbus/hv_connection.c
  stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
  stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
  stable/10/sys/dev/hyperv/vmbus/vmbus_var.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/vmbus/hv_connection.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_connection.c	Thu Jun 23 05:41:46 2016	(r302117)
+++ stable/10/sys/dev/hyperv/vmbus/hv_connection.c	Thu Jun 23 05:51:57 2016	(r302118)
@@ -336,13 +336,11 @@ vmbus_event_proc(struct vmbus_softc *sc,
 {
 	hv_vmbus_synic_event_flags *event;
 
-	event = hv_vmbus_g_context.syn_ic_event_page[cpu] +
-	    HV_VMBUS_MESSAGE_SINT;
-
 	/*
 	 * On Host with Win8 or above, the event page can be checked directly
 	 * to get the id of the channel that has the pending interrupt.
 	 */
+	event = VMBUS_SC_PCPU_GET(sc, event_flag, cpu) + HV_VMBUS_MESSAGE_SINT;
 	vmbus_event_flags_proc(event->flagsul,
 	    VMBUS_SC_PCPU_GET(sc, event_flag_cnt, cpu));
 }
@@ -352,9 +350,7 @@ vmbus_event_proc_compat(struct vmbus_sof
 {
 	hv_vmbus_synic_event_flags *event;
 
-	event = hv_vmbus_g_context.syn_ic_event_page[cpu] +
-	    HV_VMBUS_MESSAGE_SINT;
-
+	event = VMBUS_SC_PCPU_GET(sc, event_flag, cpu) + HV_VMBUS_MESSAGE_SINT;
 	if (atomic_testandclear_int(&event->flags32[0], 0)) {
 		vmbus_event_flags_proc(
 		    hv_vmbus_g_connection.recv_interrupt_page,

Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Thu Jun 23 05:41:46 2016	(r302117)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Thu Jun 23 05:51:57 2016	(r302118)
@@ -69,18 +69,16 @@ __FBSDID("$FreeBSD$");
 struct vmbus_softc	*vmbus_sc;
 
 static int vmbus_inited;
-static hv_setup_args setup_args; /* only CPU 0 supported at this time */
 
 static char *vmbus_ids[] = { "VMBUS", NULL };
 
 static void
-vmbus_msg_task(void *arg __unused, int pending __unused)
+vmbus_msg_task(void *xsc, int pending __unused)
 {
+	struct vmbus_softc *sc = xsc;
 	hv_vmbus_message *msg;
 
-	msg = hv_vmbus_g_context.syn_ic_msg_page[curcpu] +
-	    HV_VMBUS_MESSAGE_SINT;
-
+	msg = VMBUS_SC_PCPU_GET(sc, message, curcpu) + HV_VMBUS_MESSAGE_SINT;
 	for (;;) {
 		const hv_vmbus_channel_msg_table_entry *entry;
 		hv_vmbus_channel_msg_header *hdr;
@@ -143,7 +141,7 @@ hv_vmbus_isr(struct vmbus_softc *sc, str
 	sc->vmbus_event_proc(sc, cpu);
 
 	/* Check if there are actual msgs to be process */
-	msg_base = hv_vmbus_g_context.syn_ic_msg_page[cpu];
+	msg_base = VMBUS_SC_PCPU_GET(sc, message, cpu);
 	msg = msg_base + HV_VMBUS_TIMER_SINT;
 
 	/* we call eventtimer process the message */
@@ -209,7 +207,7 @@ hv_vector_handler(struct trapframe *trap
 }
 
 static void
-vmbus_synic_setup(void *arg)
+vmbus_synic_setup(void *arg __unused)
 {
 	struct vmbus_softc *sc = vmbus_get_softc();
 	int			cpu;
@@ -219,7 +217,6 @@ vmbus_synic_setup(void *arg)
 	hv_vmbus_synic_scontrol sctrl;
 	hv_vmbus_synic_sint	shared_sint;
 	uint64_t		version;
-	hv_setup_args* 		setup_args = (hv_setup_args *)arg;
 
 	cpu = PCPU_GET(cpuid);
 
@@ -228,19 +225,13 @@ vmbus_synic_setup(void *arg)
 	 */
 	version = rdmsr(HV_X64_MSR_SVERSION);
 
-	hv_vmbus_g_context.syn_ic_msg_page[cpu] =
-	    setup_args->page_buffers[2 * cpu];
-	hv_vmbus_g_context.syn_ic_event_page[cpu] =
-	    setup_args->page_buffers[2 * cpu + 1];
-
 	/*
 	 * Setup the Synic's message page
 	 */
-
 	simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
 	simp.u.simp_enabled = 1;
-	simp.u.base_simp_gpa = ((hv_get_phys_addr(
-	    hv_vmbus_g_context.syn_ic_msg_page[cpu])) >> PAGE_SHIFT);
+	simp.u.base_simp_gpa =
+	    VMBUS_SC_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT;
 
 	wrmsr(HV_X64_MSR_SIMP, simp.as_uint64_t);
 
@@ -249,8 +240,8 @@ vmbus_synic_setup(void *arg)
 	 */
 	siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
 	siefp.u.siefp_enabled = 1;
-	siefp.u.base_siefp_gpa = ((hv_get_phys_addr(
-	    hv_vmbus_g_context.syn_ic_event_page[cpu])) >> PAGE_SHIFT);
+	siefp.u.base_siefp_gpa =
+	    VMBUS_SC_PCPU_GET(sc, event_flag_dma.hv_paddr, cpu) >> PAGE_SHIFT;
 
 	wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
 
@@ -328,6 +319,47 @@ vmbus_synic_teardown(void *arg)
 	wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
 }
 
+static void
+vmbus_dma_alloc(struct vmbus_softc *sc)
+{
+	int cpu;
+
+	CPU_FOREACH(cpu) {
+		/*
+		 * Per-cpu messages and event flags.
+		 */
+		VMBUS_SC_PCPU_GET(sc, message, cpu) = hyperv_dmamem_alloc(
+		    bus_get_dma_tag(sc->vmbus_dev), PAGE_SIZE, 0, PAGE_SIZE,
+		    VMBUS_SC_PCPU_PTR(sc, message_dma, cpu),
+		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
+		VMBUS_SC_PCPU_GET(sc, event_flag, cpu) = hyperv_dmamem_alloc(
+		    bus_get_dma_tag(sc->vmbus_dev), PAGE_SIZE, 0, PAGE_SIZE,
+		    VMBUS_SC_PCPU_PTR(sc, event_flag_dma, cpu),
+		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
+	}
+}
+
+static void
+vmbus_dma_free(struct vmbus_softc *sc)
+{
+	int cpu;
+
+	CPU_FOREACH(cpu) {
+		if (VMBUS_SC_PCPU_GET(sc, message, cpu) != NULL) {
+			hyperv_dmamem_free(
+			    VMBUS_SC_PCPU_PTR(sc, message_dma, cpu),
+			    VMBUS_SC_PCPU_GET(sc, message, cpu));
+			VMBUS_SC_PCPU_GET(sc, message, cpu) = NULL;
+		}
+		if (VMBUS_SC_PCPU_GET(sc, event_flag, cpu) != NULL) {
+			hyperv_dmamem_free(
+			    VMBUS_SC_PCPU_PTR(sc, event_flag_dma, cpu),
+			    VMBUS_SC_PCPU_GET(sc, event_flag, cpu));
+			VMBUS_SC_PCPU_GET(sc, event_flag, cpu) = NULL;
+		}
+	}
+}
+
 static int
 vmbus_read_ivar(
 	device_t	dev,
@@ -560,7 +592,7 @@ static int
 vmbus_bus_init(void)
 {
 	struct vmbus_softc *sc;
-	int i, n, ret, cpu;
+	int ret, cpu;
 	char buf[MAXCOMLEN + 1];
 	cpuset_t cpu_mask;
 
@@ -587,9 +619,6 @@ vmbus_bus_init(void)
 	CPU_FOREACH(cpu) {
 		snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
 		intrcnt_add(buf, VMBUS_SC_PCPU_PTR(sc, intr_cnt, cpu));
-
-		for (i = 0; i < 2; i++)
-			setup_args.page_buffers[2 * cpu + i] = NULL;
 	}
 
 	/*
@@ -623,9 +652,9 @@ vmbus_bus_init(void)
 		    "hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
 		    &hv_vmbus_g_context.hv_msg_tq[cpu]);
 		taskqueue_start_threads(&hv_vmbus_g_context.hv_msg_tq[cpu], 1,
-		     PI_NET, "hvmsg%d", cpu);
+		    PI_NET, "hvmsg%d", cpu);
 		TASK_INIT(&hv_vmbus_g_context.hv_msg_task[cpu], 0,
-		    vmbus_msg_task, NULL);
+		    vmbus_msg_task, sc);
 
 		CPU_SETOF(cpu, &cpu_mask);
 		TASK_INIT(&cpuset_task, 0, vmbus_cpuset_setthread_task,
@@ -634,22 +663,17 @@ vmbus_bus_init(void)
 		    &cpuset_task);
 		taskqueue_drain(hv_vmbus_g_context.hv_msg_tq[cpu],
 		    &cpuset_task);
-
-		/*
-		 * Prepare the per cpu msg and event pages to be called on
-		 * each cpu.
-		 */
-		for(i = 0; i < 2; i++) {
-			setup_args.page_buffers[2 * cpu + i] =
-				malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO);
-		}
 	}
 
+	/*
+	 * Allocate vmbus DMA stuffs.
+	 */
+	vmbus_dma_alloc(sc);
+
 	if (bootverbose)
 		printf("VMBUS: Calling smp_rendezvous, smp_started = %d\n",
 		    smp_started);
-
-	smp_rendezvous(NULL, vmbus_synic_setup, NULL, &setup_args);
+	smp_rendezvous(NULL, vmbus_synic_setup, NULL, NULL);
 
 	/*
 	 * Connect to VMBus in the root partition
@@ -673,13 +697,8 @@ vmbus_bus_init(void)
 
 	return (ret);
 
-	cleanup1:
-	/*
-	 * Free pages alloc'ed
-	 */
-	for (n = 0; n < 2 * MAXCPU; n++)
-		if (setup_args.page_buffers[n] != NULL)
-			free(setup_args.page_buffers[n], M_DEVBUF);
+cleanup1:
+	vmbus_dma_free(sc);
 
 	/*
 	 * remove swi and vmbus callback vector;
@@ -755,10 +774,7 @@ vmbus_detach(device_t dev)
 
 	smp_rendezvous(NULL, vmbus_synic_teardown, NULL, NULL);
 
-	for(i = 0; i < 2 * MAXCPU; i++) {
-		if (setup_args.page_buffers[i] != NULL)
-			free(setup_args.page_buffers[i], M_DEVBUF);
-	}
+	vmbus_dma_free(sc);
 
 	/* remove swi */
 	CPU_FOREACH(i) {

Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Thu Jun 23 05:41:46 2016	(r302117)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Thu Jun 23 05:51:57 2016	(r302118)
@@ -203,8 +203,6 @@ union vmbus_event_flags;
 typedef struct {
 	hv_bool_uint8_t	syn_ic_initialized;
 
-	struct vmbus_message	*syn_ic_msg_page[MAXCPU];
-	union vmbus_event_flags	*syn_ic_event_page[MAXCPU];
 	/*
 	 * For FreeBSD cpuid to Hyper-V vcpuid mapping.
 	 */
@@ -755,8 +753,4 @@ void			hv_et_intr(struct trapframe*);
 /* Wait for device creation */
 void			vmbus_scan(void);
 
-typedef struct {
-	void		*page_buffers[2 * MAXCPU];
-} hv_setup_args;
-
 #endif  /* __HYPERV_PRIV_H__ */

Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h	Thu Jun 23 05:41:46 2016	(r302117)
+++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h	Thu Jun 23 05:51:57 2016	(r302118)
@@ -30,10 +30,18 @@
 #define _VMBUS_VAR_H_
 
 #include <sys/param.h>
+#include <sys/bus_dma.h>
+#include <dev/hyperv/include/hyperv_busdma.h>
 
 struct vmbus_pcpu_data {
-	int		event_flag_cnt;	/* # of event flags */
-	u_long		*intr_cnt;
+	u_long			*intr_cnt;	/* Hyper-V interrupt counter */
+	struct vmbus_message	*message;	/* shared messages */
+	int			event_flag_cnt;	/* # of event flags */
+	union vmbus_event_flags	*event_flag;	/* shared event flags */
+
+	/* Rarely used fields */
+	struct hyperv_dma	message_dma;	/* busdma glue */
+	struct hyperv_dma	event_flag_dma;	/* busdma glue */
 } __aligned(CACHE_LINE_SIZE);
 
 struct vmbus_softc {



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