Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Revert recent pic optimizations until I have more t...



details:   https://anonhg.NetBSD.org/src/rev/0765b5880980
branches:  trunk
changeset: 1019976:0765b5880980
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sat Mar 27 12:15:08 2021 +0000

description:
Revert recent pic optimizations until I have more time to work on this.

diffstat:

 sys/arch/aarch64/include/cpu.h  |    5 +-
 sys/arch/arm/include/cpu.h      |    5 +-
 sys/arch/arm/pic/pic.c          |  111 +++++++++++++++++++++++++++------------
 sys/arch/arm/pic/pic_splfuncs.c |   71 ++++++-------------------
 sys/arch/arm/pic/picvar.h       |   24 ++------
 5 files changed, 103 insertions(+), 113 deletions(-)

diffs (truncated from 481 to 300 lines):

diff -r 4fcba999852a -r 0765b5880980 sys/arch/aarch64/include/cpu.h
--- a/sys/arch/aarch64/include/cpu.h    Sat Mar 27 12:14:49 2021 +0000
+++ b/sys/arch/aarch64/include/cpu.h    Sat Mar 27 12:15:08 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.33 2021/02/21 17:07:06 jmcneill Exp $ */
+/* $NetBSD: cpu.h,v 1.34 2021/03/27 12:15:09 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc.
@@ -104,9 +104,6 @@
        int ci_hwpl;            /* current hardware priority */
        volatile u_int ci_softints;
        volatile u_int ci_intr_depth;
-       volatile uint32_t ci_blocked_pics;
-       volatile uint32_t ci_pending_pics;
-       volatile uint32_t ci_pending_ipls;
 
        int ci_kfpu_spl;
 
diff -r 4fcba999852a -r 0765b5880980 sys/arch/arm/include/cpu.h
--- a/sys/arch/arm/include/cpu.h        Sat Mar 27 12:14:49 2021 +0000
+++ b/sys/arch/arm/include/cpu.h        Sat Mar 27 12:15:08 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.116 2021/02/21 15:00:04 jmcneill Exp $       */
+/*     $NetBSD: cpu.h,v 1.117 2021/03/27 12:15:08 jmcneill Exp $       */
 
 /*
  * Copyright (c) 1994-1996 Mark Brinicombe.
@@ -190,9 +190,6 @@
 
        volatile u_int  ci_intr_depth;  /* */
        volatile u_int  ci_softints;
-       volatile uint32_t ci_blocked_pics;
-       volatile uint32_t ci_pending_pics;
-       volatile uint32_t ci_pending_ipls;
 
        lwp_t *         ci_lastlwp;     /* last lwp */
 
diff -r 4fcba999852a -r 0765b5880980 sys/arch/arm/pic/pic.c
--- a/sys/arch/arm/pic/pic.c    Sat Mar 27 12:14:49 2021 +0000
+++ b/sys/arch/arm/pic/pic.c    Sat Mar 27 12:15:08 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pic.c,v 1.69 2021/02/21 17:07:45 jmcneill Exp $        */
+/*     $NetBSD: pic.c,v 1.70 2021/03/27 12:15:09 jmcneill Exp $        */
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -33,7 +33,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.69 2021/02/21 17:07:45 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.70 2021/03/27 12:15:09 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -59,20 +59,43 @@
 #include <arm/pic/picvar.h>
 
 #if defined(__HAVE_PIC_PENDING_INTRS)
-
 /*
  * This implementation of pending interrupts on a MULTIPROCESSOR system makes
  * the assumption that a PIC (pic_softc) shall only have all its interrupts
  * come from the same CPU.  In other words, interrupts from a single PIC will
  * not be distributed among multiple CPUs.
  */
+struct pic_pending {
+       volatile uint32_t blocked_pics;
+       volatile uint32_t pending_pics;
+       volatile uint32_t pending_ipls;
+};
 static uint32_t
        pic_find_pending_irqs_by_ipl(struct pic_softc *, size_t, uint32_t, int);
 static struct pic_softc *
-       pic_list_find_pic_by_pending_ipl(struct cpu_info *, uint32_t);
+       pic_list_find_pic_by_pending_ipl(struct pic_pending *, uint32_t);
+static void
+       pic_deliver_irqs(struct pic_pending *, struct pic_softc *, int, void *);
 static void
-       pic_deliver_irqs(struct cpu_info *, struct pic_softc *, int, void *);
+       pic_list_deliver_irqs(struct pic_pending *, register_t, int, void *);
 
+#ifdef MULTIPROCESSOR
+percpu_t *pic_pending_percpu;
+static struct pic_pending *
+pic_pending_get(void)
+{
+       return percpu_getref(pic_pending_percpu);
+}
+static void
+pic_pending_put(struct pic_pending *pend)
+{
+       percpu_putref(pic_pending_percpu);
+}
+#else
+struct pic_pending pic_pending;
+#define        pic_pending_get()       (&pic_pending)
+#define        pic_pending_put(pend)   __nothing
+#endif /* MULTIPROCESSOR */
 #endif /* __HAVE_PIC_PENDING_INTRS */
 
 struct pic_softc *pic_list[PIC_MAXPICS];
@@ -95,6 +118,20 @@
 
 static int pic_init(void);
 
+#ifdef __HAVE_PIC_SET_PRIORITY
+void
+pic_set_priority(struct cpu_info *ci, int newipl)
+{
+       register_t psw = DISABLE_INTERRUPT_SAVE();
+       if (pic_list[0] != NULL)
+               (pic_list[0]->pic_ops->pic_set_priority)(pic_list[0], newipl);
+       ci->ci_cpl = newipl;
+       if ((psw & I32_bit) == 0) {
+               ENABLE_INTERRUPT();
+       }
+}
+#endif
+
 #ifdef MULTIPROCESSOR
 int
 pic_ipi_ast(void *arg)
@@ -138,9 +175,7 @@
 int
 pic_ipi_kpreempt(void *arg)
 {
-       struct lwp *l = curlwp;
-
-       l->l_md.md_astpending |= __BIT(1);
+       atomic_or_uint(&curcpu()->ci_astpending, __BIT(1));
        return 1;
 }
 #endif /* __HAVE_PREEMPTION */
@@ -229,14 +264,15 @@
 pic_mark_pending_source(struct pic_softc *pic, struct intrsource *is)
 {
        const uint32_t ipl_mask = __BIT(is->is_ipl);
-       struct cpu_info * const ci = curcpu();
 
        atomic_or_32(&pic->pic_pending_irqs[is->is_irq >> 5],
            __BIT(is->is_irq & 0x1f));
 
        atomic_or_32(&pic->pic_pending_ipls, ipl_mask);
-       atomic_or_32(&ci->ci_pending_ipls, ipl_mask);
-       atomic_or_32(&ci->ci_pending_pics, __BIT(pic->pic_id));
+       struct pic_pending *pend = pic_pending_get();
+       atomic_or_32(&pend->pending_ipls, ipl_mask);
+       atomic_or_32(&pend->pending_pics, __BIT(pic->pic_id));
+       pic_pending_put(pend);
 }
 
 void
@@ -257,7 +293,6 @@
        struct intrsource ** const isbase = &pic->pic_sources[irq_base];
        struct intrsource *is;
        volatile uint32_t *ipending = &pic->pic_pending_irqs[irq_base >> 5];
-       struct cpu_info * const ci = curcpu();
        uint32_t ipl_mask = 0;
 
        if (pending == 0)
@@ -280,8 +315,10 @@
        }
 
        atomic_or_32(&pic->pic_pending_ipls, ipl_mask);
-       atomic_or_32(&ci->ci_pending_ipls, ipl_mask);
-       atomic_or_32(&ci->ci_pending_pics, __BIT(pic->pic_id));
+       struct pic_pending *pend = pic_pending_get();
+       atomic_or_32(&pend->pending_ipls, ipl_mask);
+       atomic_or_32(&pend->pending_pics, __BIT(pic->pic_id));
+       pic_pending_put(pend);
        return ipl_mask;
 }
 
@@ -350,7 +387,7 @@
 
 #if defined(__HAVE_PIC_PENDING_INTRS)
 void
-pic_deliver_irqs(struct cpu_info *ci, struct pic_softc *pic, int ipl,
+pic_deliver_irqs(struct pic_pending *pend, struct pic_softc *pic, int ipl,
     void *frame)
 {
        const uint32_t ipl_mask = __BIT(ipl);
@@ -431,7 +468,7 @@
                } while (pending_irqs);
                if (blocked_irqs) {
                        atomic_or_32(iblocked, blocked_irqs);
-                       atomic_or_32(&ci->ci_blocked_pics, __BIT(pic->pic_id));
+                       atomic_or_32(&pend->blocked_pics, __BIT(pic->pic_id));
                }
        }
 
@@ -441,15 +478,15 @@
         * about these.
         */
        if (atomic_and_32_nv(&pic->pic_pending_ipls, ~ipl_mask) == 0)
-               atomic_and_32(&ci->ci_pending_pics, ~__BIT(pic->pic_id));
+               atomic_and_32(&pend->pending_pics, ~__BIT(pic->pic_id));
 }
 
-void
-pic_list_unblock_irqs(struct cpu_info *ci)
+static void
+pic_list_unblock_irqs(struct pic_pending *pend)
 {
-       uint32_t blocked_pics = ci->ci_blocked_pics;
+       uint32_t blocked_pics = pend->blocked_pics;
 
-       ci->ci_blocked_pics = 0;
+       pend->blocked_pics = 0;
 
        for (;;) {
                struct pic_softc *pic;
@@ -486,9 +523,9 @@
 }
 
 struct pic_softc *
-pic_list_find_pic_by_pending_ipl(struct cpu_info *ci, uint32_t ipl_mask)
+pic_list_find_pic_by_pending_ipl(struct pic_pending *pend, uint32_t ipl_mask)
 {
-       uint32_t pending_pics = ci->ci_pending_pics;
+       uint32_t pending_pics = pend->pending_pics;
        struct pic_softc *pic;
 
        for (;;) {
@@ -505,17 +542,17 @@
 }
 
 void
-pic_list_deliver_irqs(struct cpu_info *ci, register_t psw, int ipl,
+pic_list_deliver_irqs(struct pic_pending *pend, register_t psw, int ipl,
     void *frame)
 {
        const uint32_t ipl_mask = __BIT(ipl);
        struct pic_softc *pic;
 
-       while ((pic = pic_list_find_pic_by_pending_ipl(ci, ipl_mask)) != NULL) {
-               pic_deliver_irqs(ci, pic, ipl, frame);
+       while ((pic = pic_list_find_pic_by_pending_ipl(pend, ipl_mask)) != NULL) {
+               pic_deliver_irqs(pend, pic, ipl, frame);
                KASSERT((pic->pic_pending_ipls & ipl_mask) == 0);
        }
-       atomic_and_32(&ci->ci_pending_ipls, ~ipl_mask);
+       atomic_and_32(&pend->pending_ipls, ~ipl_mask);
 }
 #endif /* __HAVE_PIC_PENDING_INTRS */
 
@@ -528,23 +565,24 @@
                return;
        }
 #if defined(__HAVE_PIC_PENDING_INTRS)
-       while ((ci->ci_pending_ipls & ~__BIT(newipl)) > __BIT(newipl)) {
-               KASSERT(ci->ci_pending_ipls < __BIT(NIPL));
+       struct pic_pending *pend = pic_pending_get();
+       while ((pend->pending_ipls & ~__BIT(newipl)) > __BIT(newipl)) {
+               KASSERT(pend->pending_ipls < __BIT(NIPL));
                for (;;) {
-                       int ipl = 31 - __builtin_clz(ci->ci_pending_ipls);
+                       int ipl = 31 - __builtin_clz(pend->pending_ipls);
                        KASSERT(ipl < NIPL);
                        if (ipl <= newipl)
                                break;
 
                        pic_set_priority(ci, ipl);
-                       pic_list_deliver_irqs(ci, psw, ipl, frame);
-                       pic_list_unblock_irqs(ci);
+                       pic_list_deliver_irqs(pend, psw, ipl, frame);
+                       pic_list_unblock_irqs(pend);
                }
        }
+       pic_pending_put(pend);
 #endif /* __HAVE_PIC_PENDING_INTRS */
 #ifdef __HAVE_PREEMPTION
-       struct lwp *l = curlwp;
-       if (newipl == IPL_NONE && (l->l_md.md_astpending & __BIT(1))) {
+       if (newipl == IPL_NONE && (ci->ci_astpending & __BIT(1))) {
                pic_set_priority(ci, IPL_SCHED);
                kpreempt(0);
        }
@@ -604,6 +642,11 @@
 
        KASSERT(strlen(pic->pic_name) > 0);
 
+#if defined(__HAVE_PIC_PENDING_INTRS) && defined(MULTIPROCESSOR)
+       if (__predict_false(pic_pending_percpu == NULL))
+               pic_pending_percpu = percpu_alloc(sizeof(struct pic_pending));
+#endif /* __HAVE_PIC_PENDING_INTRS && MULTIPROCESSOR */
+
        mutex_enter(&pic_lock);
        if (irqbase == PIC_IRQBASE_ALLOC) {
                irqbase = pic_lastbase;
diff -r 4fcba999852a -r 0765b5880980 sys/arch/arm/pic/pic_splfuncs.c
--- a/sys/arch/arm/pic/pic_splfuncs.c   Sat Mar 27 12:14:49 2021 +0000
+++ b/sys/arch/arm/pic/pic_splfuncs.c   Sat Mar 27 12:15:08 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pic_splfuncs.c,v 1.19 2021/03/01 11:29:14 jmcneill Exp $       */
+/*     $NetBSD: pic_splfuncs.c,v 1.20 2021/03/27 12:15:09 jmcneill Exp $       */
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.



Home | Main Index | Thread Index | Old Index