Author: sephe
Date: Tue May 24 06:01:39 2016
New Revision: 300572
URL: https://svnweb.freebsd.org/changeset/base/300572

Log:
  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:
  head/sys/dev/hyperv/vmbus/hv_connection.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
  head/sys/dev/hyperv/vmbus/vmbus_var.h

Modified: head/sys/dev/hyperv/vmbus/hv_connection.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_connection.c   Tue May 24 05:51:51 2016        
(r300571)
+++ head/sys/dev/hyperv/vmbus/hv_connection.c   Tue May 24 06:01:39 2016        
(r300572)
@@ -333,13 +333,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));
 }
@@ -349,9 +347,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: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c    Tue May 24 05:51:51 
2016        (r300571)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c    Tue May 24 06:01:39 
2016        (r300572)
@@ -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,
@@ -490,7 +522,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;
 
@@ -517,9 +549,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;
        }
 
        /*
@@ -549,23 +578,18 @@ vmbus_bus_init(void)
                    &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, NULL);
-
-               /*
-                * 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);
-               }
+                   vmbus_msg_task, sc);
        }
 
+       /*
+        * 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
@@ -589,13 +613,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;
@@ -675,10 +694,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: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h   Tue May 24 05:51:51 2016        
(r300571)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h   Tue May 24 06:01:39 2016        
(r300572)
@@ -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: head/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_var.h       Tue May 24 05:51:51 2016        
(r300571)
+++ head/sys/dev/hyperv/vmbus/vmbus_var.h       Tue May 24 06:01:39 2016        
(r300572)
@@ -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 {
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to