git: 9fb6718d1b18 - main - smp: Dynamically allocate the stoppcbs array

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 25 May 2023 22:10:29 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=9fb6718d1b180c341373b25c03dbfc221ddee311

commit 9fb6718d1b180c341373b25c03dbfc221ddee311
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2023-04-25 16:09:24 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2023-05-25 22:09:55 +0000

    smp: Dynamically allocate the stoppcbs array
    
    This avoids bloating the kernel image when MAXCPU is large.
    
    A follow-up patch for kgdb and other kernel debuggers is needed since
    the stoppcbs symbol is now a pointer.  Bump __FreeBSD_version so that
    debuggers can use osreldate to figure out how to handle stoppcbs.
    
    PR:             269572
    MFC after:      never
    Reviewed by:    mjg, emaste
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D39806
---
 sys/amd64/include/kdb.h          | 2 --
 sys/arm/arm/mp_machdep.c         | 1 -
 sys/arm/include/kdb.h            | 2 --
 sys/arm/include/smp.h            | 3 ---
 sys/arm64/arm64/mp_machdep.c     | 2 --
 sys/arm64/include/smp.h          | 3 ---
 sys/i386/include/kdb.h           | 2 --
 sys/kern/subr_kdb.c              | 6 +++---
 sys/kern/subr_smp.c              | 7 +++++++
 sys/powerpc/include/kdb.h        | 2 --
 sys/powerpc/include/smp.h        | 2 --
 sys/powerpc/powerpc/mp_machdep.c | 1 -
 sys/riscv/include/kdb.h          | 2 --
 sys/riscv/include/smp.h          | 2 --
 sys/riscv/riscv/mp_machdep.c     | 2 --
 sys/sys/param.h                  | 2 +-
 sys/sys/smp.h                    | 3 +++
 sys/x86/include/x86_smp.h        | 1 -
 sys/x86/x86/mp_x86.c             | 1 -
 19 files changed, 14 insertions(+), 32 deletions(-)

diff --git a/sys/amd64/include/kdb.h b/sys/amd64/include/kdb.h
index e2a16ccca0eb..6612bfce6361 100644
--- a/sys/amd64/include/kdb.h
+++ b/sys/amd64/include/kdb.h
@@ -34,8 +34,6 @@
 #include <machine/frame.h>
 #include <machine/psl.h>
 
-#define	KDB_STOPPEDPCB(pc)	&stoppcbs[pc->pc_cpuid]
-
 int kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access);
 int kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size);
 
diff --git a/sys/arm/arm/mp_machdep.c b/sys/arm/arm/mp_machdep.c
index 36a38291dd3a..b823270eb1c9 100644
--- a/sys/arm/arm/mp_machdep.c
+++ b/sys/arm/arm/mp_machdep.c
@@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
 
 /* used to hold the AP's until we are ready to release them */
 struct mtx ap_boot_mtx;
-struct pcb stoppcbs[MAXCPU];
 
 /* # of Applications processors */
 volatile int mp_naps;
diff --git a/sys/arm/include/kdb.h b/sys/arm/include/kdb.h
index fde37d148fb6..3fed40807761 100644
--- a/sys/arm/include/kdb.h
+++ b/sys/arm/include/kdb.h
@@ -36,8 +36,6 @@
 #include <machine/frame.h>
 #include <machine/psl.h>
 
-#define	KDB_STOPPEDPCB(pc)	&stoppcbs[pc->pc_cpuid]
-
 extern void kdb_cpu_clear_singlestep(void);
 extern void kdb_cpu_set_singlestep(void);
 boolean_t kdb_cpu_pc_is_singlestep(db_addr_t);
diff --git a/sys/arm/include/smp.h b/sys/arm/include/smp.h
index 4f1545872a4e..fbb769151de6 100644
--- a/sys/arm/include/smp.h
+++ b/sys/arm/include/smp.h
@@ -29,7 +29,4 @@ void	ipi_selected(cpuset_t cpus, u_int ipi);
 void	platform_mp_setmaxid(void);
 void	platform_mp_start_ap(void);
 
-/* global data in mp_machdep.c */
-extern struct pcb               stoppcbs[];
-
 #endif /* !_MACHINE_SMP_H_ */
diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c
index 9a4997358f8a..9dd1182e5721 100644
--- a/sys/arm64/arm64/mp_machdep.c
+++ b/sys/arm64/arm64/mp_machdep.c
@@ -126,8 +126,6 @@ static void ipi_preempt(void *);
 static void ipi_rendezvous(void *);
 static void ipi_stop(void *);
 
-struct pcb stoppcbs[MAXCPU];
-
 #ifdef FDT
 static u_int fdt_cpuid;
 #endif
diff --git a/sys/arm64/include/smp.h b/sys/arm64/include/smp.h
index 538981a954f0..1404a72f13cc 100644
--- a/sys/arm64/include/smp.h
+++ b/sys/arm64/include/smp.h
@@ -49,7 +49,4 @@ void	ipi_all_but_self(u_int ipi);
 void	ipi_cpu(int cpu, u_int ipi);
 void	ipi_selected(cpuset_t cpus, u_int ipi);
 
-/* global data in mp_machdep.c */
-extern struct pcb               stoppcbs[];
-
 #endif /* !_MACHINE_SMP_H_ */
diff --git a/sys/i386/include/kdb.h b/sys/i386/include/kdb.h
index 53fbe6cbe908..47a8ff86fd44 100644
--- a/sys/i386/include/kdb.h
+++ b/sys/i386/include/kdb.h
@@ -34,8 +34,6 @@
 #include <machine/frame.h>
 #include <machine/psl.h>
 
-#define	KDB_STOPPEDPCB(pc)	&stoppcbs[pc->pc_cpuid]
-
 int kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access);
 int kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size);
 
diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c
index 79b61f67b1e0..f8b37c2319b0 100644
--- a/sys/kern/subr_kdb.c
+++ b/sys/kern/subr_kdb.c
@@ -627,18 +627,18 @@ kdb_reenter_silent(void)
 struct pcb *
 kdb_thr_ctx(struct thread *thr)
 {
-#if defined(SMP) && defined(KDB_STOPPEDPCB)
+#ifdef SMP
 	struct pcpu *pc;
 #endif
 
 	if (thr == curthread)
 		return (&kdb_pcb);
 
-#if defined(SMP) && defined(KDB_STOPPEDPCB)
+#ifdef SMP
 	STAILQ_FOREACH(pc, &cpuhead, pc_allcpu)  {
 		if (pc->pc_curthread == thr &&
 		    CPU_ISSET(pc->pc_cpuid, &stopped_cpus))
-			return (KDB_STOPPEDPCB(pc));
+			return (&stoppcbs[pc->pc_cpuid]);
 	}
 #endif
 	return (thr->td_pcb);
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index 00e2396d5774..cdee6fbebb3c 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysctl.h>
 
 #include <machine/cpu.h>
+#include <machine/pcb.h>
 #include <machine/smp.h>
 
 #include "opt_sched.h"
@@ -76,6 +77,9 @@ int mp_maxcpus = MAXCPU;
 volatile int smp_started;
 u_int mp_maxid;
 
+/* Array of CPU contexts saved during a panic. */
+struct pcb *stoppcbs;
+
 static SYSCTL_NODE(_kern, OID_AUTO, smp,
     CTLFLAG_RD | CTLFLAG_CAPRD | CTLFLAG_MPSAFE, NULL,
     "Kernel SMP");
@@ -178,6 +182,9 @@ mp_start(void *dummy)
 	if (mp_ncores < 0)
 		mp_ncores = mp_ncpus;
 
+	stoppcbs = mallocarray(mp_maxid + 1, sizeof(struct pcb), M_DEVBUF,
+	    M_WAITOK | M_ZERO);
+
 	cpu_mp_announce();
 }
 SYSINIT(cpu_mp, SI_SUB_CPU, SI_ORDER_THIRD, mp_start, NULL);
diff --git a/sys/powerpc/include/kdb.h b/sys/powerpc/include/kdb.h
index f399b7523143..6594acb77fd1 100644
--- a/sys/powerpc/include/kdb.h
+++ b/sys/powerpc/include/kdb.h
@@ -40,8 +40,6 @@
 void kdb_cpu_clear_singlestep(void);
 void kdb_cpu_set_singlestep(void);
 
-#define KDB_STOPPEDPCB(pc)      &stoppcbs[pc->pc_cpuid]
-
 static __inline void
 kdb_cpu_sync_icache(unsigned char *addr, size_t size)
 {
diff --git a/sys/powerpc/include/smp.h b/sys/powerpc/include/smp.h
index 67e9d51f0bc4..6fcff18ffa4b 100644
--- a/sys/powerpc/include/smp.h
+++ b/sys/powerpc/include/smp.h
@@ -61,8 +61,6 @@ uintptr_t cpudep_ap_bootstrap(void);
 void	cpudep_ap_setup(void);
 void	machdep_ap_bootstrap(void);
 
-extern struct pcb stoppcbs[];
-
 #endif /* !LOCORE */
 #endif /* _KERNEL */
 #endif /* !_MACHINE_SMP_H */
diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c
index df602912b234..59a000e8e24d 100644
--- a/sys/powerpc/powerpc/mp_machdep.c
+++ b/sys/powerpc/powerpc/mp_machdep.c
@@ -66,7 +66,6 @@ volatile static int ap_awake;
 volatile static u_int ap_letgo;
 volatile static u_quad_t ap_timebase;
 static struct mtx ap_boot_mtx;
-struct pcb stoppcbs[MAXCPU];
 
 void
 machdep_ap_bootstrap(void)
diff --git a/sys/riscv/include/kdb.h b/sys/riscv/include/kdb.h
index 0fdff26bb432..24c6145853c3 100644
--- a/sys/riscv/include/kdb.h
+++ b/sys/riscv/include/kdb.h
@@ -31,8 +31,6 @@
 
 #include <machine/cpufunc.h>
 
-#define	KDB_STOPPEDPCB(pc)	&stoppcbs[pc->pc_cpuid]
-
 static __inline void
 kdb_cpu_clear_singlestep(void)
 {
diff --git a/sys/riscv/include/smp.h b/sys/riscv/include/smp.h
index a1d588f31567..1760647903cb 100644
--- a/sys/riscv/include/smp.h
+++ b/sys/riscv/include/smp.h
@@ -52,6 +52,4 @@ void ipi_all_but_self(u_int ipi);
 void ipi_cpu(int cpu, u_int ipi);
 void ipi_selected(cpuset_t cpus, u_int ipi);
 
-extern struct pcb stoppcbs[];
-
 #endif /* !_MACHINE_SMP_H_ */
diff --git a/sys/riscv/riscv/mp_machdep.c b/sys/riscv/riscv/mp_machdep.c
index cd75f2dbbb73..018d7c653304 100644
--- a/sys/riscv/riscv/mp_machdep.c
+++ b/sys/riscv/riscv/mp_machdep.c
@@ -88,8 +88,6 @@ static device_attach_t riscv64_cpu_attach;
 
 static int ipi_handler(void *);
 
-struct pcb stoppcbs[MAXCPU];
-
 extern uint32_t boot_hart;
 extern cpuset_t all_harts;
 
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 25fac3efde1d..5bdc3e2ebee4 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -76,7 +76,7 @@
  * cannot include sys/param.h and should only be updated here.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1400088
+#define __FreeBSD_version 1400089
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/smp.h b/sys/sys/smp.h
index 4583dc4350c9..7c3ce7f4ff8d 100644
--- a/sys/sys/smp.h
+++ b/sys/sys/smp.h
@@ -178,6 +178,9 @@ extern int smp_threads_per_core;
 extern cpuset_t all_cpus;
 extern cpuset_t cpuset_domain[MAXMEMDOM]; 	/* CPUs in each NUMA domain. */
 
+struct pcb;
+extern struct pcb *stoppcbs;
+
 /*
  * Macro allowing us to determine whether a CPU is absent at any given
  * time, thus permitting us to configure sparse maps of cpuid-dependent
diff --git a/sys/x86/include/x86_smp.h b/sys/x86/include/x86_smp.h
index 9d8e1c4ebaec..356d8b881962 100644
--- a/sys/x86/include/x86_smp.h
+++ b/sys/x86/include/x86_smp.h
@@ -30,7 +30,6 @@ extern unsigned int boot_address;
 /* global data in mp_x86.c */
 extern int mp_naps;
 extern int boot_cpu_id;
-extern struct pcb stoppcbs[];
 extern int cpu_apic_ids[];
 extern int bootAP;
 extern void *dpcpu;
diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c
index 34c54b27eeff..581ec0ac518a 100644
--- a/sys/x86/x86/mp_x86.c
+++ b/sys/x86/x86/mp_x86.c
@@ -99,7 +99,6 @@ int bootAP;
 void *bootstacks[MAXCPU];
 void *dpcpu;
 
-struct pcb stoppcbs[MAXCPU];
 struct susppcb **susppcbs;
 
 #ifdef COUNT_IPIS