Module Name: src Committed By: jmcneill Date: Sat Feb 20 14:51:07 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: Move 'struct pic_pending' from percpu to struct cpu_info. Saves a few instructions in splx. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.31 src/sys/arch/aarch64/include/cpu.h cvs rdiff -u -r1.114 -r1.115 src/sys/arch/arm/include/cpu.h cvs rdiff -u -r1.65 -r1.66 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.30 src/sys/arch/aarch64/include/cpu.h:1.31 --- src/sys/arch/aarch64/include/cpu.h:1.30 Mon Dec 7 10:56:12 2020 +++ src/sys/arch/aarch64/include/cpu.h Sat Feb 20 14:51:07 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.30 2020/12/07 10:56:12 jmcneill Exp $ */ +/* $NetBSD: cpu.h,v 1.31 2021/02/20 14:51:07 jmcneill Exp $ */ /*- * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc. @@ -103,6 +103,9 @@ struct cpu_info { int ci_cpl; 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.114 src/sys/arch/arm/include/cpu.h:1.115 --- src/sys/arch/arm/include/cpu.h:1.114 Mon Aug 17 01:52:59 2020 +++ src/sys/arch/arm/include/cpu.h Sat Feb 20 14:51:06 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.114 2020/08/17 01:52:59 mrg Exp $ */ +/* $NetBSD: cpu.h,v 1.115 2021/02/20 14:51:06 jmcneill Exp $ */ /* * Copyright (c) 1994-1996 Mark Brinicombe. @@ -189,6 +189,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.65 src/sys/arch/arm/pic/pic.c:1.66 --- src/sys/arch/arm/pic/pic.c:1.65 Tue Feb 16 22:12:49 2021 +++ src/sys/arch/arm/pic/pic.c Sat Feb 20 14:51:07 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: pic.c,v 1.65 2021/02/16 22:12:49 jmcneill Exp $ */ +/* $NetBSD: pic.c,v 1.66 2021/02/20 14:51:07 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.65 2021/02/16 22:12:49 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.66 2021/02/20 14:51:07 jmcneill Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -68,37 +68,15 @@ bool pic_pending_used __read_mostly = fa * 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]; @@ -281,6 +259,7 @@ 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(); if (!pic_pending_used) pic_pending_used = true; @@ -289,10 +268,8 @@ pic_mark_pending_source(struct pic_softc __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 @@ -313,14 +290,15 @@ pic_mark_pending_sources(struct pic_soft 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 (!pic_pending_used) - pic_pending_used = true; - if (pending == 0) return ipl_mask; + if (!pic_pending_used) + pic_pending_used = true; + KASSERT((irq_base & 31) == 0); (*pic->pic_ops->pic_block_irqs)(pic, irq_base, pending); @@ -338,10 +316,8 @@ 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); + atomic_or_32(&ci->ci_pending_ipls, ipl_mask); + atomic_or_32(&ci->ci_pending_pics, __BIT(pic->pic_id)); return ipl_mask; } @@ -410,7 +386,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); @@ -491,7 +467,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)); + atomic_or_32(&ci->ci_blocked_pics, __BIT(pic->pic_id)); } } @@ -501,15 +477,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)); + 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; @@ -546,9 +522,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 (;;) { @@ -565,17 +541,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); + atomic_and_32(&ci->ci_pending_ipls, ~ipl_mask); } #endif /* __HAVE_PIC_PENDING_INTRS */ @@ -588,21 +564,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_psw(ci, psw, 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))) { @@ -665,11 +639,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;