Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/hyperv hyper-v: move idt vector allocating to vmbus_...



details:   https://anonhg.NetBSD.org/src/rev/3f39447bb59e
branches:  trunk
changeset: 1029143:3f39447bb59e
user:      yamaguchi <yamaguchi%NetBSD.org@localhost>
date:      Thu Dec 23 04:06:51 2021 +0000

description:
hyper-v: move idt vector allocating to vmbus_init_interrupts_md()
for refactoring

And, the deallocating is also moved to
vmbus_deinit_interrupts_md().

reviewed by nonaka@n.o.

diffstat:

 sys/arch/x86/x86/hyperv.c  |  122 ++++++++++++++++----------------------------
 sys/dev/hyperv/hypervvar.h |    6 +-
 sys/dev/hyperv/vmbus.c     |   50 ++++++++++-------
 3 files changed, 78 insertions(+), 100 deletions(-)

diffs (truncated from 344 to 300 lines):

diff -r e6fafe2795a5 -r 3f39447bb59e sys/arch/x86/x86/hyperv.c
--- a/sys/arch/x86/x86/hyperv.c Thu Dec 23 02:45:43 2021 +0000
+++ b/sys/arch/x86/x86/hyperv.c Thu Dec 23 04:06:51 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hyperv.c,v 1.13 2021/01/28 01:57:31 jmcneill Exp $     */
+/*     $NetBSD: hyperv.c,v 1.14 2021/12/23 04:06:51 yamaguchi Exp $    */
 
 /*-
  * Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
@@ -33,7 +33,7 @@
  */
 #include <sys/cdefs.h>
 #ifdef __KERNEL_RCSID
-__KERNEL_RCSID(0, "$NetBSD: hyperv.c,v 1.13 2021/01/28 01:57:31 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hyperv.c,v 1.14 2021/12/23 04:06:51 yamaguchi Exp $");
 #endif
 #ifdef __FBSDID
 __FBSDID("$FreeBSD: head/sys/dev/hyperv/vmbus/hyperv.c 331757 2018-03-30 02:25:12Z emaste $");
@@ -755,52 +755,65 @@
 }
 
 void
-vmbus_init_interrupts_md(struct vmbus_softc *sc)
+vmbus_init_interrupts_md(struct vmbus_softc *sc, cpuid_t cpu)
 {
        extern void Xintr_hyperv_hypercall(void);
        struct vmbus_percpu_data *pd;
        struct hyperv_percpu_data *hv_pd;
-       struct idt_vec *iv = &(cpu_info_primary.ci_idtvec);
-       cpuid_t cid;
+       struct cpu_info *ci;
+       struct idt_vec *iv;
+       int hyperv_idtvec;
+       cpuid_t cpu0;
+
+       cpu0 = cpu_index(&cpu_info_primary);
 
-       if (idt_vec_is_pcpu())
-               return;
-       /*
-        * All Hyper-V ISR required resources are setup, now let's find a
-        * free IDT vector for Hyper-V ISR and set it up.
-        */
-       iv = &(cpu_info_primary.ci_idtvec);
-       cid = cpu_index(&cpu_info_primary);
-       pd = &sc->sc_percpu[cid];
+       if (cpu == cpu0 || idt_vec_is_pcpu()) {
+               /*
+                * All Hyper-V ISR required resources are setup, now let's find a
+                * free IDT vector for Hyper-V ISR and set it up.
+                */
+               ci = cpu_lookup(cpu);
+               iv = &ci->ci_idtvec;
+               mutex_enter(&cpu_lock);
+               hyperv_idtvec = idt_vec_alloc(iv,
+                   APIC_LEVEL(NIPL), IDT_INTR_HIGH);
+               mutex_exit(&cpu_lock);
+               KASSERT(hyperv_idtvec > 0);
+               idt_vec_set(iv, hyperv_idtvec, Xintr_hyperv_hypercall);
+       } else {
+               pd = &sc->sc_percpu[cpu0];
+               hv_pd = pd->md_cookie;
+               KASSERT(hv_pd != NULL && hv_pd->pd_idtvec > 0);
+               hyperv_idtvec = hv_pd->pd_idtvec;
+       }
 
        hv_pd = kmem_zalloc(sizeof(*hv_pd), KM_SLEEP);
-       mutex_enter(&cpu_lock);
-       hv_pd->pd_idtvec = idt_vec_alloc(iv,
-           APIC_LEVEL(NIPL), IDT_INTR_HIGH);
-       mutex_exit(&cpu_lock);
-       KASSERT(hv_pd->pd_idtvec > 0);
-       idt_vec_set(iv, hv_pd->pd_idtvec, Xintr_hyperv_hypercall);
+       hv_pd->pd_idtvec = hyperv_idtvec;
+       pd = &sc->sc_percpu[cpu];
        pd->md_cookie = (void *)hv_pd;
 }
 
 void
-vmbus_deinit_interrupts_md(struct vmbus_softc *sc)
+vmbus_deinit_interrupts_md(struct vmbus_softc *sc, cpuid_t cpu)
 {
        struct vmbus_percpu_data *pd;
        struct hyperv_percpu_data *hv_pd;
+       struct cpu_info *ci;
        struct idt_vec *iv;
-       cpuid_t cid;
 
-       if (idt_vec_is_pcpu())
-               return;
+       pd = &sc->sc_percpu[cpu];
+       hv_pd = pd->md_cookie;
+       KASSERT(hv_pd != NULL);
 
-       iv = &(cpu_info_primary.ci_idtvec);
-       cid = cpu_index(&cpu_info_primary);
-       pd = &sc->sc_percpu[cid];
-       hv_pd = pd->md_cookie;
+       if (cpu == cpu_index(&cpu_info_primary) ||
+           idt_vec_is_pcpu()) {
+               ci = cpu_lookup(cpu);
+               iv = &ci->ci_idtvec;
 
-       if (hv_pd->pd_idtvec > 0)
-               idt_vec_free(iv, hv_pd->pd_idtvec);
+               if (hv_pd->pd_idtvec > 0) {
+                       idt_vec_free(iv, hv_pd->pd_idtvec);
+               }
+       }
 
        pd->md_cookie = NULL;
        kmem_free(hv_pd, sizeof(*hv_pd));
@@ -810,38 +823,15 @@
 vmbus_init_synic_md(struct vmbus_softc *sc, cpuid_t cpu)
 {
        extern void Xintr_hyperv_hypercall(void);
-       struct vmbus_percpu_data *pd, *pd0;
+       struct vmbus_percpu_data *pd;
        struct hyperv_percpu_data *hv_pd;
-       struct cpu_info *ci;
-       struct idt_vec *iv;
        uint64_t val, orig;
        uint32_t sint;
        int hyperv_idtvec;
 
        pd = &sc->sc_percpu[cpu];
-
-       hv_pd = kmem_alloc(sizeof(*hv_pd), KM_SLEEP);
-       pd->md_cookie = (void *)hv_pd;
-
-       /* Allocate IDT vector for ISR and set it up. */
-       if (idt_vec_is_pcpu()) {
-               ci = curcpu();
-               iv = &ci->ci_idtvec;
-
-               mutex_enter(&cpu_lock);
-               hyperv_idtvec = idt_vec_alloc(iv, APIC_LEVEL(NIPL), IDT_INTR_HIGH);
-               mutex_exit(&cpu_lock);
-               KASSERT(hyperv_idtvec > 0);
-               idt_vec_set(iv, hyperv_idtvec, Xintr_hyperv_hypercall);
-
-               hv_pd = kmem_alloc(sizeof(*hv_pd), KM_SLEEP);
-               hv_pd->pd_idtvec = hyperv_idtvec;
-               pd->md_cookie = hv_pd;
-       } else {
-               pd0 = &sc->sc_percpu[cpu_index(&cpu_info_primary)];
-               hv_pd = pd0->md_cookie;
-               hyperv_idtvec = hv_pd->pd_idtvec;
-       }
+       hv_pd = pd->md_cookie;
+       hyperv_idtvec = hv_pd->pd_idtvec;
 
        /*
         * Setup the SynIC message.
@@ -888,10 +878,6 @@
 void
 vmbus_deinit_synic_md(struct vmbus_softc *sc, cpuid_t cpu)
 {
-       struct vmbus_percpu_data *pd;
-       struct hyperv_percpu_data *hv_pd;
-       struct cpu_info *ci;
-       struct idt_vec *iv;
        uint64_t orig;
        uint32_t sint;
 
@@ -926,22 +912,6 @@
         */
        orig = rdmsr(MSR_HV_SIEFP);
        wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
-
-       /*
-        * Free IDT vector
-        */
-       if (idt_vec_is_pcpu()) {
-               ci = curcpu();
-               iv = &ci->ci_idtvec;
-               pd = &sc->sc_percpu[cpu_index(ci)];
-               hv_pd = pd->md_cookie;
-
-               if (hv_pd->pd_idtvec > 0)
-                       idt_vec_free(iv, hv_pd->pd_idtvec);
-
-               pd->md_cookie = NULL;
-               kmem_free(hv_pd, sizeof(*hv_pd));
-       }
 }
 
 static int
diff -r e6fafe2795a5 -r 3f39447bb59e sys/dev/hyperv/hypervvar.h
--- a/sys/dev/hyperv/hypervvar.h        Thu Dec 23 02:45:43 2021 +0000
+++ b/sys/dev/hyperv/hypervvar.h        Thu Dec 23 04:06:51 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hypervvar.h,v 1.4 2019/12/10 12:20:20 nonaka Exp $     */
+/*     $NetBSD: hypervvar.h,v 1.5 2021/12/23 04:06:51 yamaguchi Exp $  */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -68,8 +68,8 @@
 uint32_t hyperv_get_vcpuid(cpuid_t);
 
 struct vmbus_softc;
-void   vmbus_init_interrupts_md(struct vmbus_softc *);
-void   vmbus_deinit_interrupts_md(struct vmbus_softc *);
+void   vmbus_init_interrupts_md(struct vmbus_softc *, cpuid_t);
+void   vmbus_deinit_interrupts_md(struct vmbus_softc *, cpuid_t);
 void   vmbus_init_synic_md(struct vmbus_softc *, cpuid_t);
 void   vmbus_deinit_synic_md(struct vmbus_softc *, cpuid_t);
 
diff -r e6fafe2795a5 -r 3f39447bb59e sys/dev/hyperv/vmbus.c
--- a/sys/dev/hyperv/vmbus.c    Thu Dec 23 02:45:43 2021 +0000
+++ b/sys/dev/hyperv/vmbus.c    Thu Dec 23 04:06:51 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vmbus.c,v 1.14 2021/08/07 16:19:11 thorpej Exp $       */
+/*     $NetBSD: vmbus.c,v 1.15 2021/12/23 04:06:51 yamaguchi Exp $     */
 /*     $OpenBSD: hyperv.c,v 1.43 2017/06/27 13:56:15 mikeb Exp $       */
 
 /*-
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vmbus.c,v 1.14 2021/08/07 16:19:11 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vmbus.c,v 1.15 2021/12/23 04:06:51 yamaguchi Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -68,8 +68,8 @@
 static void    vmbus_free_dma(struct vmbus_softc *);
 static int     vmbus_init_interrupts(struct vmbus_softc *);
 static void    vmbus_deinit_interrupts(struct vmbus_softc *);
-static void    vmbus_init_synic(void *, void *);
-static void    vmbus_deinit_synic(void *, void *);
+static void    vmbus_init_interrupts_pcpu(void *, void *);
+static void    vmbus_deinit_interrupts_pcpu(void *, void *);
 
 static int     vmbus_connect(struct vmbus_softc *);
 static int     vmbus_cmd(struct vmbus_softc *, void *, size_t, void *, size_t,
@@ -313,8 +313,11 @@
 vmbus_attach_deferred(device_t self)
 {
        struct vmbus_softc *sc = device_private(self);
+       uint64_t xc;
 
-       xc_wait(xc_broadcast(0, vmbus_init_synic, sc, NULL));
+       xc = xc_broadcast(0, vmbus_init_interrupts_pcpu,
+           sc, NULL);
+       xc_wait(xc);
 }
 
 int
@@ -404,6 +407,7 @@
 static int
 vmbus_init_interrupts(struct vmbus_softc *sc)
 {
+       uint64_t xc;
 
        TAILQ_INIT(&sc->sc_reqs);
        mutex_init(&sc->sc_req_lock, MUTEX_DEFAULT, IPL_NET);
@@ -420,14 +424,15 @@
        if (sc->sc_msg_sih == NULL)
                return -1;
 
-       vmbus_init_interrupts_md(sc);
-
        kcpuset_create(&sc->sc_intr_cpuset, true);
        if (cold) {
                /* Initialize other CPUs later. */
-               vmbus_init_synic(sc, NULL);
-       } else
-               xc_wait(xc_broadcast(0, vmbus_init_synic, sc, NULL));
+               vmbus_init_interrupts_pcpu(sc, NULL);
+       } else {
+               xc = xc_broadcast(0, vmbus_init_interrupts_pcpu,
+                   sc, NULL);
+               xc_wait(xc);
+       }
        atomic_or_32(&sc->sc_flags, VMBUS_SCFLAG_SYNIC);
 
        return 0;
@@ -436,14 +441,16 @@
 static void
 vmbus_deinit_interrupts(struct vmbus_softc *sc)
 {
+       uint64_t xc;
 
-       if (ISSET(sc->sc_flags, VMBUS_SCFLAG_SYNIC)) {
-               if (cold)
-                       vmbus_deinit_synic(sc, NULL);
-               else
-                       xc_wait(xc_broadcast(0, vmbus_deinit_synic, sc, NULL));
-               atomic_and_32(&sc->sc_flags, (uint32_t)~VMBUS_SCFLAG_SYNIC);
+       if (cold) {
+               vmbus_deinit_interrupts_pcpu(sc, NULL);
+       } else {
+               xc = xc_broadcast(0, vmbus_deinit_interrupts_pcpu,
+                   sc, NULL);
+               xc_wait(xc);
        }
+       atomic_and_32(&sc->sc_flags, (uint32_t)~VMBUS_SCFLAG_SYNIC);
 



Home | Main Index | Thread Index | Old Index