Module Name:    src
Committed By:   cherry
Date:           Sat Nov 17 05:26:46 UTC 2018

Modified Files:
        src/sys/arch/xen/x86: hypervisor_machdep.c

Log Message:
Use hypervisor provided interface to unmask specific ports.

Although at first glance this looks suboptimal, the unmask operation
fast path does not use hypervisor_unmask_event(). Instead, it directly
operates on the mask and pending bit arrays to provide what would
effectively be an "auto mask/eoi" semantic.

This change is thus not in the fast path, and has the advantage of
performance improvements since cross CPU state updates etc. is handled
within the hypervisor instead of domU IPIs.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/xen/x86/hypervisor_machdep.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/xen/x86/hypervisor_machdep.c
diff -u src/sys/arch/xen/x86/hypervisor_machdep.c:1.29 src/sys/arch/xen/x86/hypervisor_machdep.c:1.30
--- src/sys/arch/xen/x86/hypervisor_machdep.c:1.29	Fri Oct 26 05:33:21 2018
+++ src/sys/arch/xen/x86/hypervisor_machdep.c	Sat Nov 17 05:26:46 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: hypervisor_machdep.c,v 1.29 2018/10/26 05:33:21 cherry Exp $	*/
+/*	$NetBSD: hypervisor_machdep.c,v 1.30 2018/11/17 05:26:46 cherry Exp $	*/
 
 /*
  *
@@ -54,7 +54,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hypervisor_machdep.c,v 1.29 2018/10/26 05:33:21 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hypervisor_machdep.c,v 1.30 2018/11/17 05:26:46 cherry Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -322,47 +322,22 @@ hypervisor_send_event(struct cpu_info *c
 void
 hypervisor_unmask_event(unsigned int ev)
 {
-	volatile shared_info_t *s = HYPERVISOR_shared_info;
-	CPU_INFO_ITERATOR cii;
-	struct cpu_info *ci;
-	volatile struct vcpu_info *vci;
+
+	KASSERT(ev > 0 && ev < NR_EVENT_CHANNELS);
 
 #ifdef PORT_DEBUG
 	if (ev == PORT_DEBUG)
 		printf("hypervisor_unmask_event %d\n", ev);
 #endif
 
-	xen_atomic_clear_bit(&s->evtchn_mask[0], ev);
-	/*
-	 * The following is basically the equivalent of
-	 * 'hw_resend_irq'. Just like a real IO-APIC we 'lose the
-	 * interrupt edge' if the channel is masked.
-	 */
-	if (!xen_atomic_test_bit(&s->evtchn_pending[0], ev))
-		return;
+	/* Xen unmasks the evtchn_mask[0]:ev bit for us. */
+	evtchn_op_t op;
+	op.cmd = EVTCHNOP_unmask;
+	op.u.unmask.port = ev;
+	if (HYPERVISOR_event_channel_op(&op) != 0)
+		panic("Failed to unmask event %d\n", ev);
 
-	for (CPU_INFO_FOREACH(cii, ci)) {
-		if (!xen_atomic_test_bit(&ci->ci_evtmask[0], ev))
-			continue;
-		vci = ci->ci_vcpu;
-		if (__predict_true(ci == curcpu())) {
-			if (!xen_atomic_test_and_set_bit(&vci->evtchn_pending_sel,
-				ev>>LONG_SHIFT))
-				xen_atomic_set_bit(&vci->evtchn_upcall_pending, 0);
-		}
-		if (!vci->evtchn_upcall_mask) {
-			if (__predict_true(ci == curcpu())) {
-				hypervisor_force_callback();
-			} else {
-				if (__predict_false(
-				    xen_send_ipi(ci, XEN_IPI_HVCB))) {
-					panic("xen_send_ipi(cpu%d, "
-					    "XEN_IPI_HVCB) failed\n",
-					    (int) ci->ci_cpuid);
-				}
-			}
-		}
-	}
+	return;
 }
 
 void

Reply via email to