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
This commit is contained in:
Mark Johnston 2023-04-25 12:09:24 -04:00
parent fed03614bd
commit 9fb6718d1b
19 changed files with 14 additions and 32 deletions

View File

@ -34,8 +34,6 @@
#include <machine/frame.h> #include <machine/frame.h>
#include <machine/psl.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_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); int kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size);

View File

@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
/* used to hold the AP's until we are ready to release them */ /* used to hold the AP's until we are ready to release them */
struct mtx ap_boot_mtx; struct mtx ap_boot_mtx;
struct pcb stoppcbs[MAXCPU];
/* # of Applications processors */ /* # of Applications processors */
volatile int mp_naps; volatile int mp_naps;

View File

@ -36,8 +36,6 @@
#include <machine/frame.h> #include <machine/frame.h>
#include <machine/psl.h> #include <machine/psl.h>
#define KDB_STOPPEDPCB(pc) &stoppcbs[pc->pc_cpuid]
extern void kdb_cpu_clear_singlestep(void); extern void kdb_cpu_clear_singlestep(void);
extern void kdb_cpu_set_singlestep(void); extern void kdb_cpu_set_singlestep(void);
boolean_t kdb_cpu_pc_is_singlestep(db_addr_t); boolean_t kdb_cpu_pc_is_singlestep(db_addr_t);

View File

@ -29,7 +29,4 @@ void ipi_selected(cpuset_t cpus, u_int ipi);
void platform_mp_setmaxid(void); void platform_mp_setmaxid(void);
void platform_mp_start_ap(void); void platform_mp_start_ap(void);
/* global data in mp_machdep.c */
extern struct pcb stoppcbs[];
#endif /* !_MACHINE_SMP_H_ */ #endif /* !_MACHINE_SMP_H_ */

View File

@ -126,8 +126,6 @@ static void ipi_preempt(void *);
static void ipi_rendezvous(void *); static void ipi_rendezvous(void *);
static void ipi_stop(void *); static void ipi_stop(void *);
struct pcb stoppcbs[MAXCPU];
#ifdef FDT #ifdef FDT
static u_int fdt_cpuid; static u_int fdt_cpuid;
#endif #endif

View File

@ -49,7 +49,4 @@ void ipi_all_but_self(u_int ipi);
void ipi_cpu(int cpu, u_int ipi); void ipi_cpu(int cpu, u_int ipi);
void ipi_selected(cpuset_t cpus, 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_ */ #endif /* !_MACHINE_SMP_H_ */

View File

@ -34,8 +34,6 @@
#include <machine/frame.h> #include <machine/frame.h>
#include <machine/psl.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_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); int kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size);

View File

@ -627,18 +627,18 @@ kdb_reenter_silent(void)
struct pcb * struct pcb *
kdb_thr_ctx(struct thread *thr) kdb_thr_ctx(struct thread *thr)
{ {
#if defined(SMP) && defined(KDB_STOPPEDPCB) #ifdef SMP
struct pcpu *pc; struct pcpu *pc;
#endif #endif
if (thr == curthread) if (thr == curthread)
return (&kdb_pcb); return (&kdb_pcb);
#if defined(SMP) && defined(KDB_STOPPEDPCB) #ifdef SMP
STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) {
if (pc->pc_curthread == thr && if (pc->pc_curthread == thr &&
CPU_ISSET(pc->pc_cpuid, &stopped_cpus)) CPU_ISSET(pc->pc_cpuid, &stopped_cpus))
return (KDB_STOPPEDPCB(pc)); return (&stoppcbs[pc->pc_cpuid]);
} }
#endif #endif
return (thr->td_pcb); return (thr->td_pcb);

View File

@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <machine/pcb.h>
#include <machine/smp.h> #include <machine/smp.h>
#include "opt_sched.h" #include "opt_sched.h"
@ -76,6 +77,9 @@ int mp_maxcpus = MAXCPU;
volatile int smp_started; volatile int smp_started;
u_int mp_maxid; u_int mp_maxid;
/* Array of CPU contexts saved during a panic. */
struct pcb *stoppcbs;
static SYSCTL_NODE(_kern, OID_AUTO, smp, static SYSCTL_NODE(_kern, OID_AUTO, smp,
CTLFLAG_RD | CTLFLAG_CAPRD | CTLFLAG_MPSAFE, NULL, CTLFLAG_RD | CTLFLAG_CAPRD | CTLFLAG_MPSAFE, NULL,
"Kernel SMP"); "Kernel SMP");
@ -178,6 +182,9 @@ mp_start(void *dummy)
if (mp_ncores < 0) if (mp_ncores < 0)
mp_ncores = mp_ncpus; mp_ncores = mp_ncpus;
stoppcbs = mallocarray(mp_maxid + 1, sizeof(struct pcb), M_DEVBUF,
M_WAITOK | M_ZERO);
cpu_mp_announce(); cpu_mp_announce();
} }
SYSINIT(cpu_mp, SI_SUB_CPU, SI_ORDER_THIRD, mp_start, NULL); SYSINIT(cpu_mp, SI_SUB_CPU, SI_ORDER_THIRD, mp_start, NULL);

View File

@ -40,8 +40,6 @@
void kdb_cpu_clear_singlestep(void); void kdb_cpu_clear_singlestep(void);
void kdb_cpu_set_singlestep(void); void kdb_cpu_set_singlestep(void);
#define KDB_STOPPEDPCB(pc) &stoppcbs[pc->pc_cpuid]
static __inline void static __inline void
kdb_cpu_sync_icache(unsigned char *addr, size_t size) kdb_cpu_sync_icache(unsigned char *addr, size_t size)
{ {

View File

@ -61,8 +61,6 @@ uintptr_t cpudep_ap_bootstrap(void);
void cpudep_ap_setup(void); void cpudep_ap_setup(void);
void machdep_ap_bootstrap(void); void machdep_ap_bootstrap(void);
extern struct pcb stoppcbs[];
#endif /* !LOCORE */ #endif /* !LOCORE */
#endif /* _KERNEL */ #endif /* _KERNEL */
#endif /* !_MACHINE_SMP_H */ #endif /* !_MACHINE_SMP_H */

View File

@ -66,7 +66,6 @@ volatile static int ap_awake;
volatile static u_int ap_letgo; volatile static u_int ap_letgo;
volatile static u_quad_t ap_timebase; volatile static u_quad_t ap_timebase;
static struct mtx ap_boot_mtx; static struct mtx ap_boot_mtx;
struct pcb stoppcbs[MAXCPU];
void void
machdep_ap_bootstrap(void) machdep_ap_bootstrap(void)

View File

@ -31,8 +31,6 @@
#include <machine/cpufunc.h> #include <machine/cpufunc.h>
#define KDB_STOPPEDPCB(pc) &stoppcbs[pc->pc_cpuid]
static __inline void static __inline void
kdb_cpu_clear_singlestep(void) kdb_cpu_clear_singlestep(void)
{ {

View File

@ -52,6 +52,4 @@ void ipi_all_but_self(u_int ipi);
void ipi_cpu(int cpu, u_int ipi); void ipi_cpu(int cpu, u_int ipi);
void ipi_selected(cpuset_t cpus, u_int ipi); void ipi_selected(cpuset_t cpus, u_int ipi);
extern struct pcb stoppcbs[];
#endif /* !_MACHINE_SMP_H_ */ #endif /* !_MACHINE_SMP_H_ */

View File

@ -88,8 +88,6 @@ static device_attach_t riscv64_cpu_attach;
static int ipi_handler(void *); static int ipi_handler(void *);
struct pcb stoppcbs[MAXCPU];
extern uint32_t boot_hart; extern uint32_t boot_hart;
extern cpuset_t all_harts; extern cpuset_t all_harts;

View File

@ -76,7 +76,7 @@
* cannot include sys/param.h and should only be updated here. * cannot include sys/param.h and should only be updated here.
*/ */
#undef __FreeBSD_version #undef __FreeBSD_version
#define __FreeBSD_version 1400088 #define __FreeBSD_version 1400089
/* /*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

View File

@ -178,6 +178,9 @@ extern int smp_threads_per_core;
extern cpuset_t all_cpus; extern cpuset_t all_cpus;
extern cpuset_t cpuset_domain[MAXMEMDOM]; /* CPUs in each NUMA domain. */ 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 * Macro allowing us to determine whether a CPU is absent at any given
* time, thus permitting us to configure sparse maps of cpuid-dependent * time, thus permitting us to configure sparse maps of cpuid-dependent

View File

@ -30,7 +30,6 @@ extern unsigned int boot_address;
/* global data in mp_x86.c */ /* global data in mp_x86.c */
extern int mp_naps; extern int mp_naps;
extern int boot_cpu_id; extern int boot_cpu_id;
extern struct pcb stoppcbs[];
extern int cpu_apic_ids[]; extern int cpu_apic_ids[];
extern int bootAP; extern int bootAP;
extern void *dpcpu; extern void *dpcpu;

View File

@ -99,7 +99,6 @@ int bootAP;
void *bootstacks[MAXCPU]; void *bootstacks[MAXCPU];
void *dpcpu; void *dpcpu;
struct pcb stoppcbs[MAXCPU];
struct susppcb **susppcbs; struct susppcb **susppcbs;
#ifdef COUNT_IPIS #ifdef COUNT_IPIS