Source-Changes-HG archive

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

[src/trunk]: src/sys/arch By default, events are bound to CPU 0 (exept for IP...



details:   https://anonhg.NetBSD.org/src/rev/0775290770b8
branches:  trunk
changeset: 930771:0775290770b8
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Mon Apr 13 22:54:11 2020 +0000

description:
By default, events are bound to CPU 0 (exept for IPIs and VTIMERs which
are bound to a different CPU at creation time).
Recent MI changes caused the scheduler to choose a different CPU when
probing and attaching xennet devices (I guess it's the xenbus thread which
runs on a different CPU). This cause the callback to be called on a different
CPU than the one expected by the kernel, and the event is ignored.
It is handled when the clock causes the callback to be called on the right
CPU, which is why xennet still run, but slowly.

Change event_set_handler() to do a EVTCHNOP_bind_vcpu if requested to,
and make sure we don't do it for IPIs and VIRQs (for theses, the op fails).

diffstat:

 sys/arch/x86/include/cpu.h    |   5 +----
 sys/arch/xen/include/evtchn.h |   4 ++--
 sys/arch/xen/x86/xen_intr.c   |   6 +++---
 sys/arch/xen/x86/xen_ipi.c    |  13 +++++++------
 sys/arch/xen/xen/clock.c      |  16 ++++++----------
 sys/arch/xen/xen/evtchn.c     |  24 +++++++++++++++++++-----
 6 files changed, 38 insertions(+), 30 deletions(-)

diffs (249 lines):

diff -r 51fb701f0368 -r 0775290770b8 sys/arch/x86/include/cpu.h
--- a/sys/arch/x86/include/cpu.h        Mon Apr 13 22:22:19 2020 +0000
+++ b/sys/arch/x86/include/cpu.h        Mon Apr 13 22:54:11 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.119 2020/04/10 14:35:26 bouyer Exp $ */
+/*     $NetBSD: cpu.h,v 1.120 2020/04/13 22:54:11 bouyer Exp $ */
 
 /*
  * Copyright (c) 1990 The Regents of the University of California.
@@ -307,9 +307,6 @@
         */
        uint64_t        ci_xen_systime_ns_skew;
 
-       /* Xen periodic timer interrupt handle.  */
-       struct intrhand *ci_xen_timer_intrhand;
-
        /*
         * Clockframe for timer interrupt handler.
         * Saved at entry via event callback.
diff -r 51fb701f0368 -r 0775290770b8 sys/arch/xen/include/evtchn.h
--- a/sys/arch/xen/include/evtchn.h     Mon Apr 13 22:22:19 2020 +0000
+++ b/sys/arch/xen/include/evtchn.h     Mon Apr 13 22:54:11 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: evtchn.h,v 1.28 2020/04/06 19:26:00 jdolecek Exp $     */
+/*     $NetBSD: evtchn.h,v 1.29 2020/04/13 22:54:12 bouyer Exp $       */
 
 /*
  *
@@ -42,7 +42,7 @@
 void call_evtchn_do_event(int, struct intrframe *);
 void call_xenevt_event(int);
 int event_set_handler(int, int (*func)(void *), void *, int, const char *,
-    const char *, bool);
+    const char *, bool, bool);
 int event_remove_handler(int, int (*func)(void *), void *);
 
 struct cpu_info;
diff -r 51fb701f0368 -r 0775290770b8 sys/arch/xen/x86/xen_intr.c
--- a/sys/arch/xen/x86/xen_intr.c       Mon Apr 13 22:22:19 2020 +0000
+++ b/sys/arch/xen/x86/xen_intr.c       Mon Apr 13 22:54:11 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xen_intr.c,v 1.21 2020/04/06 19:26:00 jdolecek Exp $   */
+/*     $NetBSD: xen_intr.c,v 1.22 2020/04/13 22:54:12 bouyer Exp $     */
 
 /*-
  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xen_intr.c,v 1.21 2020/04/06 19:26:00 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_intr.c,v 1.22 2020/04/13 22:54:12 bouyer Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -170,7 +170,7 @@
                    sizeof(intrstr_buf));
 
                event_set_handler(pin, handler, arg, level, intrstr, xname,
-                   known_mpsafe);
+                   known_mpsafe, true);
 
                rih = kmem_zalloc(sizeof(*rih), cold ? KM_NOSLEEP : KM_SLEEP);
                if (rih == NULL) {
diff -r 51fb701f0368 -r 0775290770b8 sys/arch/xen/x86/xen_ipi.c
--- a/sys/arch/xen/x86/xen_ipi.c        Mon Apr 13 22:22:19 2020 +0000
+++ b/sys/arch/xen/x86/xen_ipi.c        Mon Apr 13 22:54:11 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xen_ipi.c,v 1.35 2019/12/01 15:34:46 ad Exp $ */
+/* $NetBSD: xen_ipi.c,v 1.36 2020/04/13 22:54:12 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2011, 2019 The NetBSD Foundation, Inc.
@@ -33,10 +33,10 @@
 
 /* 
  * Based on: x86/ipi.c
- * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.35 2019/12/01 15:34:46 ad Exp $");
+ * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.36 2020/04/13 22:54:12 bouyer Exp $");
  */
 
-__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.35 2019/12/01 15:34:46 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.36 2020/04/13 22:54:12 bouyer Exp $");
 
 #include "opt_ddb.h"
 
@@ -98,6 +98,8 @@
 
        ci = curcpu();
        regs = arg;
+
+       KASSERT(ci == arg);
        
        pending = atomic_swap_32(&ci->ci_ipis, 0);
 
@@ -139,8 +141,8 @@
        snprintf(intr_xname, sizeof(intr_xname), "%s ipi",
            device_xname(ci->ci_dev));
 
-       if (xen_intr_establish_xname(-1, &xen_pic, evtchn, IST_LEVEL, IPL_HIGH,
-               xen_ipi_handler, ci, true, intr_xname) == NULL) {
+       if (event_set_handler(evtchn, xen_ipi_handler, ci, IPL_HIGH, NULL,
+           intr_xname, true, false) != 0) {
                panic("%s: unable to register ipi handler\n", __func__);
                /* NOTREACHED */
        }
@@ -314,7 +316,6 @@
 {
        KASSERT(ci != NULL);
        KASSERT(intrf != NULL);
-
        ipi_cpu_handler();
 }
 
diff -r 51fb701f0368 -r 0775290770b8 sys/arch/xen/xen/clock.c
--- a/sys/arch/xen/xen/clock.c  Mon Apr 13 22:22:19 2020 +0000
+++ b/sys/arch/xen/xen/clock.c  Mon Apr 13 22:54:11 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: clock.c,v 1.80 2019/10/16 18:29:49 christos Exp $      */
+/*     $NetBSD: clock.c,v 1.81 2020/04/13 22:54:12 bouyer Exp $        */
 
 /*-
  * Copyright (c) 2017, 2018 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.80 2019/10/16 18:29:49 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.81 2020/04/13 22:54:12 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -722,14 +722,13 @@
 
        KASSERT(ci == curcpu());
        KASSERT(kpreempt_disabled());
-       KASSERT(ci->ci_xen_timer_intrhand != NULL);
 
        evtch = unbind_virq_from_evtch(VIRQ_TIMER);
        KASSERT(evtch != -1);
 
        hypervisor_mask_event(evtch);
-       xen_intr_disestablish(ci->ci_xen_timer_intrhand);
-       ci->ci_xen_timer_intrhand = NULL;
+       event_remove_handler(evtch, 
+           __FPTRCAST(int (*)(void *), xen_timer_handler), ci);
 
        aprint_verbose("Xen clock: removed event channel %d\n", evtch);
 
@@ -755,7 +754,6 @@
 
        KASSERT(ci == curcpu());
        KASSERT(kpreempt_disabled());
-       KASSERT(ci->ci_xen_timer_intrhand == NULL);
 
        evtch = bind_virq_to_evtch(VIRQ_TIMER);
        KASSERT(evtch != -1);
@@ -763,11 +761,9 @@
        snprintf(intr_xname, sizeof(intr_xname), "%s clock",
            device_xname(ci->ci_dev));
        /* XXX sketchy function pointer cast -- fix the API, please */
-       ci->ci_xen_timer_intrhand = xen_intr_establish_xname(-1, &xen_pic,
-           evtch, IST_LEVEL, IPL_CLOCK,
+       if (event_set_handler(evtch,
            __FPTRCAST(int (*)(void *), xen_timer_handler),
-           ci, true, intr_xname);
-       if (ci->ci_xen_timer_intrhand == NULL)
+           ci, IPL_CLOCK, NULL, intr_xname, true, false) != 0)
                panic("failed to establish timer interrupt handler");
 
        hypervisor_unmask_event(evtch);
diff -r 51fb701f0368 -r 0775290770b8 sys/arch/xen/xen/evtchn.c
--- a/sys/arch/xen/xen/evtchn.c Mon Apr 13 22:22:19 2020 +0000
+++ b/sys/arch/xen/xen/evtchn.c Mon Apr 13 22:54:11 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: evtchn.c,v 1.88 2020/04/06 19:26:00 jdolecek Exp $     */
+/*     $NetBSD: evtchn.c,v 1.89 2020/04/13 22:54:12 bouyer Exp $       */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -54,7 +54,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.88 2020/04/06 19:26:00 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1.89 2020/04/13 22:54:12 bouyer Exp $");
 
 #include "opt_xen.h"
 #include "isa.h"
@@ -764,7 +764,7 @@
        ih->arg = arg;
 
        if (event_set_handler(evtch, pirq_interrupt, ih, level, intrname,
-           xname, known_mpsafe) != 0) {
+           xname, known_mpsafe, true) != 0) {
                kmem_free(ih, sizeof(struct pintrhand));
                return NULL;
        }
@@ -834,12 +834,13 @@
 
 int
 event_set_handler(int evtch, int (*func)(void *), void *arg, int level,
-    const char *intrname, const char *xname, bool mpsafe)
+    const char *intrname, const char *xname, bool mpsafe, bool bind)
 {
        struct cpu_info *ci = curcpu(); /* XXX: pass in ci ? */
        struct evtsource *evts;
        struct intrhand *ih, **ihp;
        int s;
+       char intrstr_buf[INTRIDBUF];
 
 #ifdef IRQ_DEBUG
        printf("event_set_handler IRQ %d handler %p\n", evtch, func);
@@ -848,7 +849,7 @@
        KASSERTMSG(evtch >= 0, "negative evtch: %d", evtch);
        KASSERTMSG(evtch < NR_EVENT_CHANNELS,
            "evtch number %d > NR_EVENT_CHANNELS", evtch);
-       KASSERT(intrname != NULL && xname != NULL);
+       KASSERT(xname != NULL);
 
 #if 0
        printf("event_set_handler evtch %d handler %p level %d\n", evtch,
@@ -879,6 +880,10 @@
 
        /* register handler for event channel */
        if (evtsource[evtch] == NULL) {
+               evtchn_op_t op;
+               if (intrname == NULL)
+                       intrname = intr_create_intrid(-1, &xen_pic, evtch,
+                           intrstr_buf, sizeof(intrstr_buf));
                evts = kmem_zalloc(sizeof (struct evtsource),
                    KM_NOSLEEP);
                if (evts == NULL)
@@ -898,6 +903,15 @@
 
                evcnt_attach_dynamic(&evts->ev_evcnt, EVCNT_TYPE_INTR, NULL,
                    device_xname(ci->ci_dev), evts->ev_intrname);
+               if (bind) {
+                       op.cmd = EVTCHNOP_bind_vcpu;
+                       op.u.bind_vcpu.port = evtch;
+                       op.u.bind_vcpu.vcpu = ci->ci_cpuid;
+                       if (HYPERVISOR_event_channel_op(&op) != 0) {
+                               panic("Failed to bind event %d to "
+                                   "VCPU %"PRIuCPUID, evtch, ci->ci_cpuid);
+                       }
+               }
        } else {
                evts = evtsource[evtch];
                /* sort by IPL order, higher first */



Home | Main Index | Thread Index | Old Index