Module Name: src Committed By: skrll Date: Sun Aug 8 19:28:09 UTC 2021
Modified Files: src/sys/arch/aarch64/include: cpu.h src/sys/arch/arm/include: cpu.h src/sys/arch/arm/pic: pic.c Log Message: Re-apply Move 'struct pic_pending' from percpu to struct cpu_info. Saves a few instructions in splx. There is(/was) no need to use atomic operations on the percpu / cpu_info members, so don't. Finally removng the use of percpu should help avoid problems with "late" attaching cpus. To generate a diff of this commit: cvs rdiff -u -r1.36 -r1.37 src/sys/arch/aarch64/include/cpu.h cvs rdiff -u -r1.117 -r1.118 src/sys/arch/arm/include/cpu.h cvs rdiff -u -r1.70 -r1.71 src/sys/arch/arm/pic/pic.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/aarch64/include/cpu.h diff -u src/sys/arch/aarch64/include/cpu.h:1.36 src/sys/arch/aarch64/include/cpu.h:1.37 --- src/sys/arch/aarch64/include/cpu.h:1.36 Sat May 29 06:54:20 2021 +++ src/sys/arch/aarch64/include/cpu.h Sun Aug 8 19:28:08 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.36 2021/05/29 06:54:20 skrll Exp $ */ +/* $NetBSD: cpu.h,v 1.37 2021/08/08 19:28:08 skrll Exp $ */ /*- * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc. @@ -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; Index: src/sys/arch/arm/include/cpu.h diff -u src/sys/arch/arm/include/cpu.h:1.117 src/sys/arch/arm/include/cpu.h:1.118 --- src/sys/arch/arm/include/cpu.h:1.117 Sat Mar 27 12:15:08 2021 +++ src/sys/arch/arm/include/cpu.h Sun Aug 8 19:28:08 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.117 2021/03/27 12:15:08 jmcneill Exp $ */ +/* $NetBSD: cpu.h,v 1.118 2021/08/08 19:28:08 skrll Exp $ */ /* * Copyright (c) 1994-1996 Mark Brinicombe. @@ -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 */ Index: src/sys/arch/arm/pic/pic.c diff -u src/sys/arch/arm/pic/pic.c:1.70 src/sys/arch/arm/pic/pic.c:1.71 --- src/sys/arch/arm/pic/pic.c:1.70 Sat Mar 27 12:15:09 2021 +++ src/sys/arch/arm/pic/pic.c Sun Aug 8 19:28:08 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: pic.c,v 1.70 2021/03/27 12:15:09 jmcneill Exp $ */ +/* $NetBSD: pic.c,v 1.71 2021/08/08 19:28:08 skrll 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.70 2021/03/27 12:15:09 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.71 2021/08/08 19:28:08 skrll Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -65,37 +65,15 @@ __KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.70 * 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); + ci->ci_pending_ipls |= ipl_mask; + ci->ci_pending_pics |= __BIT(pic->pic_id); } void @@ -288,9 +265,10 @@ pic_mark_pending(struct pic_softc *pic, 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,9 @@ pic_mark_pending_sources(struct pic_soft } 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); + ci->ci_pending_ipls |= ipl_mask; + ci->ci_pending_pics |= __BIT(pic->pic_id); + return ipl_mask; } @@ -387,7 +364,7 @@ pic_dispatch(struct intrsource *is, void #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 +445,7 @@ pic_deliver_irqs(struct pic_pending *pen } while (pending_irqs); if (blocked_irqs) { atomic_or_32(iblocked, blocked_irqs); - atomic_or_32(&pend->blocked_pics, __BIT(pic->pic_id)); + ci->ci_blocked_pics |= __BIT(pic->pic_id); } } @@ -478,15 +455,15 @@ pic_deliver_irqs(struct pic_pending *pen * about these. */ if (atomic_and_32_nv(&pic->pic_pending_ipls, ~ipl_mask) == 0) - atomic_and_32(&pend->pending_pics, ~__BIT(pic->pic_id)); + 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 +500,9 @@ pic_list_unblock_irqs(struct pic_pending } 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 +519,17 @@ pic_list_find_pic_by_pending_ipl(struct } 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); + ci->ci_pending_ipls &= ~ipl_mask; } #endif /* __HAVE_PIC_PENDING_INTRS */ @@ -565,21 +542,19 @@ pic_do_pending_ints(register_t psw, int 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 +617,6 @@ pic_add(struct pic_softc *pic, int irqba 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;