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;

Reply via email to