From owner-svn-src-stable-10@freebsd.org Thu Jun 23 05:51:58 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id ED7FFB72E8E; Thu, 23 Jun 2016 05:51:58 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C9B4E1CF2; Thu, 23 Jun 2016 05:51:58 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u5N5pw2j089252; Thu, 23 Jun 2016 05:51:58 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u5N5pvrx089248; Thu, 23 Jun 2016 05:51:57 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201606230551.u5N5pvrx089248@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Thu, 23 Jun 2016 05:51:57 +0000 (UTC) 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 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Jun 2016 05:51:59 -0000 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 +#include +#include 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 {