Module Name:    src
Committed By:   yamaguchi
Date:           Thu Dec 23 04:06:51 UTC 2021

Modified Files:
        src/sys/arch/x86/x86: hyperv.c
        src/sys/dev/hyperv: hypervvar.h vmbus.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/x86/x86/hyperv.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/hyperv/hypervvar.h
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/hyperv/vmbus.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/x86/hyperv.c
diff -u src/sys/arch/x86/x86/hyperv.c:1.13 src/sys/arch/x86/x86/hyperv.c:1.14
--- src/sys/arch/x86/x86/hyperv.c:1.13	Thu Jan 28 01:57:31 2021
+++ src/sys/arch/x86/x86/hyperv.c	Thu Dec 23 04:06:51 2021
@@ -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 @@ hyperv_send_eom(void)
 }
 
 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;
 
-	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];
+	cpu0 = cpu_index(&cpu_info_primary);
+
+	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;
 
-	iv = &(cpu_info_primary.ci_idtvec);
-	cid = cpu_index(&cpu_info_primary);
-	pd = &sc->sc_percpu[cid];
+	pd = &sc->sc_percpu[cpu];
 	hv_pd = pd->md_cookie;
+	KASSERT(hv_pd != NULL);
 
-	if (hv_pd->pd_idtvec > 0)
-		idt_vec_free(iv, hv_pd->pd_idtvec);
+	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);
+		}
+	}
 
 	pd->md_cookie = NULL;
 	kmem_free(hv_pd, sizeof(*hv_pd));
@@ -810,38 +823,15 @@ void
 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 @@ vmbus_init_synic_md(struct vmbus_softc *
 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 @@ vmbus_deinit_synic_md(struct vmbus_softc
 	 */
 	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

Index: src/sys/dev/hyperv/hypervvar.h
diff -u src/sys/dev/hyperv/hypervvar.h:1.4 src/sys/dev/hyperv/hypervvar.h:1.5
--- src/sys/dev/hyperv/hypervvar.h:1.4	Tue Dec 10 12:20:20 2019
+++ src/sys/dev/hyperv/hypervvar.h	Thu Dec 23 04:06:51 2021
@@ -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 @@ void	hyperv_intr(void);
 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);
 

Index: src/sys/dev/hyperv/vmbus.c
diff -u src/sys/dev/hyperv/vmbus.c:1.14 src/sys/dev/hyperv/vmbus.c:1.15
--- src/sys/dev/hyperv/vmbus.c:1.14	Sat Aug  7 16:19:11 2021
+++ src/sys/dev/hyperv/vmbus.c	Thu Dec 23 04:06:51 2021
@@ -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 int	vmbus_alloc_dma(struct vmbus_
 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 @@ static void
 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 @@ vmbus_free_dma(struct vmbus_softc *sc)
 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 @@ vmbus_init_interrupts(struct vmbus_softc
 	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 @@ vmbus_init_interrupts(struct vmbus_softc
 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);
 
 	/* XXX event_tq */
 
@@ -451,12 +458,10 @@ vmbus_deinit_interrupts(struct vmbus_sof
 		softint_disestablish(sc->sc_msg_sih);
 		sc->sc_msg_sih = NULL;
 	}
-
-	vmbus_deinit_interrupts_md(sc);
 }
 
 static void
-vmbus_init_synic(void *arg1, void *arg2)
+vmbus_init_interrupts_pcpu(void *arg1, void *arg2 __unused)
 {
 	struct vmbus_softc *sc = arg1;
 	cpuid_t cpu;
@@ -467,6 +472,7 @@ vmbus_init_synic(void *arg1, void *arg2)
 	cpu = cpu_index(curcpu());
 	if (!kcpuset_isset(sc->sc_intr_cpuset, cpu)) {
 		kcpuset_atomic_set(sc->sc_intr_cpuset, cpu);
+		vmbus_init_interrupts_md(sc, cpu);
 		vmbus_init_synic_md(sc, cpu);
 	}
 
@@ -474,7 +480,7 @@ vmbus_init_synic(void *arg1, void *arg2)
 }
 
 static void
-vmbus_deinit_synic(void *arg1, void *arg2)
+vmbus_deinit_interrupts_pcpu(void *arg1, void *arg2 __unused)
 {
 	struct vmbus_softc *sc = arg1;
 	cpuid_t cpu;
@@ -484,7 +490,9 @@ vmbus_deinit_synic(void *arg1, void *arg
 
 	cpu = cpu_index(curcpu());
 	if (kcpuset_isset(sc->sc_intr_cpuset, cpu)) {
-		vmbus_deinit_synic_md(sc, cpu);
+		if (ISSET(sc->sc_flags, VMBUS_SCFLAG_SYNIC))
+			vmbus_deinit_synic_md(sc, cpu);
+		vmbus_deinit_interrupts_md(sc, cpu);
 		kcpuset_atomic_clear(sc->sc_intr_cpuset, cpu);
 	}
 

Reply via email to