diff --git a/sys/arch/aarch64/include/cpu.h b/sys/arch/aarch64/include/cpu.h index d651f53946a6..cefb779c1452 100644 --- a/sys/arch/aarch64/include/cpu.h +++ b/sys/arch/aarch64/include/cpu.h @@ -104,6 +104,9 @@ struct cpu_info { 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 --git a/sys/arch/arm/include/cpu.h b/sys/arch/arm/include/cpu.h index 688f641077a0..0b064e8b24e0 100644 --- a/sys/arch/arm/include/cpu.h +++ b/sys/arch/arm/include/cpu.h @@ -190,6 +190,9 @@ struct cpu_info { 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 --git a/sys/arch/arm/pic/pic.c b/sys/arch/arm/pic/pic.c index ace7b2dc458a..6e6983a74b21 100644 --- a/sys/arch/arm/pic/pic.c +++ b/sys/arch/arm/pic/pic.c @@ -65,37 +65,15 @@ __KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.70 2021/03/27 12:15:09 jmcneill Exp $"); * 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 pic_pending *, uint32_t); + pic_list_find_pic_by_pending_ipl(struct cpu_info *, uint32_t); static void - pic_deliver_irqs(struct pic_pending *, struct pic_softc *, int, void *); + pic_deliver_irqs(struct cpu_info *, struct pic_softc *, int, void *); static void - pic_list_deliver_irqs(struct pic_pending *, register_t, int, void *); + pic_list_deliver_irqs(struct cpu_info *, 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]; @@ -264,15 +242,14 @@ void 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); - 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); + atomic_or_32(&ci->ci_pending_ipls, ipl_mask); + atomic_or_32(&ci->ci_pending_pics, __BIT(pic->pic_id)); } void @@ -288,9 +265,10 @@ pic_mark_pending(struct pic_softc *pic, int irq) uint32_t pic_mark_pending_sources(struct pic_softc *pic, size_t irq_base, - uint32_t pending) + uint32_t pending) { struct intrsource ** const isbase = &pic->pic_sources[irq_base]; + struct cpu_info * const ci = curcpu(); struct intrsource *is; volatile uint32_t *ipending = &pic->pic_pending_irqs[irq_base >> 5]; uint32_t ipl_mask = 0; @@ -315,10 +293,8 @@ pic_mark_pending_sources(struct pic_softc *pic, size_t irq_base, } atomic_or_32(&pic->pic_pending_ipls, ipl_mask); - 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); + atomic_or_32(&ci->ci_pending_ipls, ipl_mask); + atomic_or_32(&ci->ci_pending_pics, __BIT(pic->pic_id)); return ipl_mask; } @@ -387,7 +363,7 @@ pic_dispatch(struct intrsource *is, void *frame) #if defined(__HAVE_PIC_PENDING_INTRS) void -pic_deliver_irqs(struct pic_pending *pend, struct pic_softc *pic, int ipl, +pic_deliver_irqs(struct cpu_info *ci, struct pic_softc *pic, int ipl, void *frame) { const uint32_t ipl_mask = __BIT(ipl); @@ -468,7 +444,7 @@ pic_deliver_irqs(struct pic_pending *pend, struct pic_softc *pic, int ipl, } while (pending_irqs); if (blocked_irqs) { atomic_or_32(iblocked, blocked_irqs); - atomic_or_32(&pend->blocked_pics, __BIT(pic->pic_id)); + atomic_or_32(&ci->ci_blocked_pics, __BIT(pic->pic_id)); } } @@ -478,15 +454,15 @@ pic_deliver_irqs(struct pic_pending *pend, struct pic_softc *pic, int ipl, * about these. */ if (atomic_and_32_nv(&pic->pic_pending_ipls, ~ipl_mask) == 0) - atomic_and_32(&pend->pending_pics, ~__BIT(pic->pic_id)); + atomic_and_32(&ci->ci_pending_pics, ~__BIT(pic->pic_id)); } static void -pic_list_unblock_irqs(struct pic_pending *pend) +pic_list_unblock_irqs(struct cpu_info *ci) { - uint32_t blocked_pics = pend->blocked_pics; + uint32_t blocked_pics = ci->ci_blocked_pics; - pend->blocked_pics = 0; + ci->ci_blocked_pics = 0; for (;;) { struct pic_softc *pic; @@ -523,9 +499,9 @@ pic_list_unblock_irqs(struct pic_pending *pend) } struct pic_softc * -pic_list_find_pic_by_pending_ipl(struct pic_pending *pend, uint32_t ipl_mask) +pic_list_find_pic_by_pending_ipl(struct cpu_info *ci, uint32_t ipl_mask) { - uint32_t pending_pics = pend->pending_pics; + uint32_t pending_pics = ci->ci_pending_pics; struct pic_softc *pic; for (;;) { @@ -542,17 +518,17 @@ pic_list_find_pic_by_pending_ipl(struct pic_pending *pend, uint32_t ipl_mask) } void -pic_list_deliver_irqs(struct pic_pending *pend, register_t psw, int ipl, +pic_list_deliver_irqs(struct cpu_info *ci, 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(pend, ipl_mask)) != NULL) { - pic_deliver_irqs(pend, pic, ipl, frame); + while ((pic = pic_list_find_pic_by_pending_ipl(ci, ipl_mask)) != NULL) { + pic_deliver_irqs(ci, pic, ipl, frame); KASSERT((pic->pic_pending_ipls & ipl_mask) == 0); } - atomic_and_32(&pend->pending_ipls, ~ipl_mask); + atomic_and_32(&ci->ci_pending_ipls, ~ipl_mask); } #endif /* __HAVE_PIC_PENDING_INTRS */ @@ -565,21 +541,19 @@ pic_do_pending_ints(register_t psw, int newipl, void *frame) return; } #if defined(__HAVE_PIC_PENDING_INTRS) - struct pic_pending *pend = pic_pending_get(); - while ((pend->pending_ipls & ~__BIT(newipl)) > __BIT(newipl)) { - KASSERT(pend->pending_ipls < __BIT(NIPL)); + while ((ci->ci_pending_ipls & ~__BIT(newipl)) > __BIT(newipl)) { + KASSERT(ci->ci_pending_ipls < __BIT(NIPL)); for (;;) { - int ipl = 31 - __builtin_clz(pend->pending_ipls); + int ipl = 31 - __builtin_clz(ci->ci_pending_ipls); KASSERT(ipl < NIPL); if (ipl <= newipl) break; pic_set_priority(ci, ipl); - pic_list_deliver_irqs(pend, psw, ipl, frame); - pic_list_unblock_irqs(pend); + pic_list_deliver_irqs(ci, psw, ipl, frame); + pic_list_unblock_irqs(ci); } } - pic_pending_put(pend); #endif /* __HAVE_PIC_PENDING_INTRS */ #ifdef __HAVE_PREEMPTION if (newipl == IPL_NONE && (ci->ci_astpending & __BIT(1))) { @@ -642,11 +616,6 @@ pic_add(struct pic_softc *pic, int irqbase) 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;