From owner-svn-src-head@freebsd.org Tue May 24 06:42:15 2016 Return-Path: Delivered-To: svn-src-head@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 DDA87B488BA; Tue, 24 May 2016 06:42:15 +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 B486C1736; Tue, 24 May 2016 06:42:15 +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 u4O6gEC7066580; Tue, 24 May 2016 06:42:14 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u4O6gE47066579; Tue, 24 May 2016 06:42:14 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201605240642.u4O6gE47066579@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Tue, 24 May 2016 06:42:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r300574 - head/sys/dev/hyperv/vmbus X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 May 2016 06:42:16 -0000 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); }