- Do not handle the per-CPU containers in mbuf code as though the cpuids
were indices in a dense array. The cpuids are a sparse set and treat them as such, setting up containers only for CPUs activated during mb_init(). - Fix netstat(1) and systat(1) to treat the per-CPU stats area as a sparse map, in accordance with the above. This allows us to properly boot with certain CPUs disactivated. However, if we later decide to re-activate said CPUs, we will barf until we decide to implement CPU spinon/spinoff callback hooks to allow for said CPUs' per-CPU containers to get configured on their activation. Reported by: mjacob Partially (sys/ diffs) Submitted by: mjacob
This commit is contained in:
parent
99b3dc42ad
commit
49f854f926
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=80399
@ -301,6 +301,11 @@ cpu_mp_probe(void)
|
||||
|
||||
/* XXX: Need to check for valid platforms here. */
|
||||
|
||||
boot_cpu_id = PCPU_GET(cpuid);
|
||||
KASSERT(boot_cpu_id == hwrpb->rpb_primary_cpu_id,
|
||||
("cpu_mp_probe() called on non-primary CPU"));
|
||||
all_cpus = 1 << boot_cpu_id;
|
||||
|
||||
mp_ncpus = 1;
|
||||
|
||||
/* Make sure we have at least one secondary CPU. */
|
||||
@ -324,16 +329,12 @@ cpu_mp_probe(void)
|
||||
}
|
||||
|
||||
void
|
||||
cpu_mp_start()
|
||||
cpu_mp_start(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mtx_init(&ap_boot_mtx, "ap boot", MTX_SPIN);
|
||||
|
||||
boot_cpu_id = PCPU_GET(cpuid);
|
||||
KASSERT(boot_cpu_id == hwrpb->rpb_primary_cpu_id,
|
||||
("mp_start() called on non-primary CPU"));
|
||||
all_cpus = 1 << boot_cpu_id;
|
||||
for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
|
||||
struct pcs *pcsp;
|
||||
|
||||
|
@ -406,6 +406,12 @@ i386_mp_probe(void)
|
||||
int
|
||||
cpu_mp_probe(void)
|
||||
{
|
||||
/*
|
||||
* Record BSP in CPU map
|
||||
* This is done here so that MBUF init code works correctly.
|
||||
*/
|
||||
all_cpus = 1;
|
||||
|
||||
return (mp_capable);
|
||||
}
|
||||
|
||||
@ -1929,9 +1935,6 @@ start_all_aps(u_int boot_addr)
|
||||
mpbiosreason = inb(CMOS_DATA);
|
||||
#endif
|
||||
|
||||
/* record BSP in CPU map */
|
||||
all_cpus = 1;
|
||||
|
||||
/* set up temporary P==V mapping for AP boot */
|
||||
/* XXX this is a hack, we should boot the AP on its own stack/PTD */
|
||||
kptbase = (uintptr_t)(void *)KPTphys;
|
||||
|
@ -406,6 +406,12 @@ i386_mp_probe(void)
|
||||
int
|
||||
cpu_mp_probe(void)
|
||||
{
|
||||
/*
|
||||
* Record BSP in CPU map
|
||||
* This is done here so that MBUF init code works correctly.
|
||||
*/
|
||||
all_cpus = 1;
|
||||
|
||||
return (mp_capable);
|
||||
}
|
||||
|
||||
@ -1929,9 +1935,6 @@ start_all_aps(u_int boot_addr)
|
||||
mpbiosreason = inb(CMOS_DATA);
|
||||
#endif
|
||||
|
||||
/* record BSP in CPU map */
|
||||
all_cpus = 1;
|
||||
|
||||
/* set up temporary P==V mapping for AP boot */
|
||||
/* XXX this is a hack, we should boot the AP on its own stack/PTD */
|
||||
kptbase = (uintptr_t)(void *)KPTphys;
|
||||
|
@ -406,6 +406,12 @@ i386_mp_probe(void)
|
||||
int
|
||||
cpu_mp_probe(void)
|
||||
{
|
||||
/*
|
||||
* Record BSP in CPU map
|
||||
* This is done here so that MBUF init code works correctly.
|
||||
*/
|
||||
all_cpus = 1;
|
||||
|
||||
return (mp_capable);
|
||||
}
|
||||
|
||||
@ -1929,9 +1935,6 @@ start_all_aps(u_int boot_addr)
|
||||
mpbiosreason = inb(CMOS_DATA);
|
||||
#endif
|
||||
|
||||
/* record BSP in CPU map */
|
||||
all_cpus = 1;
|
||||
|
||||
/* set up temporary P==V mapping for AP boot */
|
||||
/* XXX this is a hack, we should boot the AP on its own stack/PTD */
|
||||
kptbase = (uintptr_t)(void *)KPTphys;
|
||||
|
@ -406,6 +406,12 @@ i386_mp_probe(void)
|
||||
int
|
||||
cpu_mp_probe(void)
|
||||
{
|
||||
/*
|
||||
* Record BSP in CPU map
|
||||
* This is done here so that MBUF init code works correctly.
|
||||
*/
|
||||
all_cpus = 1;
|
||||
|
||||
return (mp_capable);
|
||||
}
|
||||
|
||||
@ -1929,9 +1935,6 @@ start_all_aps(u_int boot_addr)
|
||||
mpbiosreason = inb(CMOS_DATA);
|
||||
#endif
|
||||
|
||||
/* record BSP in CPU map */
|
||||
all_cpus = 1;
|
||||
|
||||
/* set up temporary P==V mapping for AP boot */
|
||||
/* XXX this is a hack, we should boot the AP on its own stack/PTD */
|
||||
kptbase = (uintptr_t)(void *)KPTphys;
|
||||
|
@ -406,6 +406,12 @@ i386_mp_probe(void)
|
||||
int
|
||||
cpu_mp_probe(void)
|
||||
{
|
||||
/*
|
||||
* Record BSP in CPU map
|
||||
* This is done here so that MBUF init code works correctly.
|
||||
*/
|
||||
all_cpus = 1;
|
||||
|
||||
return (mp_capable);
|
||||
}
|
||||
|
||||
@ -1929,9 +1935,6 @@ start_all_aps(u_int boot_addr)
|
||||
mpbiosreason = inb(CMOS_DATA);
|
||||
#endif
|
||||
|
||||
/* record BSP in CPU map */
|
||||
all_cpus = 1;
|
||||
|
||||
/* set up temporary P==V mapping for AP boot */
|
||||
/* XXX this is a hack, we should boot the AP on its own stack/PTD */
|
||||
kptbase = (uintptr_t)(void *)KPTphys;
|
||||
|
@ -406,6 +406,12 @@ i386_mp_probe(void)
|
||||
int
|
||||
cpu_mp_probe(void)
|
||||
{
|
||||
/*
|
||||
* Record BSP in CPU map
|
||||
* This is done here so that MBUF init code works correctly.
|
||||
*/
|
||||
all_cpus = 1;
|
||||
|
||||
return (mp_capable);
|
||||
}
|
||||
|
||||
@ -1929,9 +1935,6 @@ start_all_aps(u_int boot_addr)
|
||||
mpbiosreason = inb(CMOS_DATA);
|
||||
#endif
|
||||
|
||||
/* record BSP in CPU map */
|
||||
all_cpus = 1;
|
||||
|
||||
/* set up temporary P==V mapping for AP boot */
|
||||
/* XXX this is a hack, we should boot the AP on its own stack/PTD */
|
||||
kptbase = (uintptr_t)(void *)KPTphys;
|
||||
|
@ -71,6 +71,7 @@ SYSCTL_INT(_machdep, OID_AUTO, forward_irq_enabled, CTLFLAG_RW,
|
||||
int
|
||||
cpu_mp_probe()
|
||||
{
|
||||
all_cpus = 1; /* Needed for MB init code */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,12 @@
|
||||
/*
|
||||
* Maximum number of PCPU containers. If you know what you're doing you could
|
||||
* explicitly define MBALLOC_NCPU to be exactly the number of CPUs on your
|
||||
* system during compilation, and thus prevent kernel structure bloats.
|
||||
* system during compilation, and thus prevent kernel structure bloat.
|
||||
*
|
||||
* SMP and non-SMP kernels clearly have a different number of possible cpus,
|
||||
* but because we cannot assume a dense array of CPUs, we always allocate
|
||||
* and traverse PCPU containers up to NCPU amount and merely check for
|
||||
* CPU availability.
|
||||
*/
|
||||
#ifdef MBALLOC_NCPU
|
||||
#define NCPU MBALLOC_NCPU
|
||||
@ -57,12 +62,18 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SMP and non-SMP kernels clearly have a different number of possible cpus.
|
||||
* Macros allowing us to determine whether or not a given CPU's container
|
||||
* should be configured during mb_init().
|
||||
* XXX: Eventually we may want to provide hooks for CPU spinon/spinoff that
|
||||
* will allow us to configure the containers on spinon/spinoff. As it
|
||||
* stands, booting with CPU x disactivated and activating CPU x only
|
||||
* after bootup will lead to disaster and CPU x's container will be
|
||||
* uninitialized.
|
||||
*/
|
||||
#ifdef SMP
|
||||
#define NCPU_PRESENT mp_ncpus
|
||||
#define CPU_ABSENT(x) ((all_cpus & (1 << x)) == 0)
|
||||
#else
|
||||
#define NCPU_PRESENT 1
|
||||
#define CPU_ABSENT(x) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -388,7 +399,10 @@ mb_init(void *dummy)
|
||||
/*
|
||||
* Allocate and initialize PCPU containers.
|
||||
*/
|
||||
for (i = 0; i < NCPU_PRESENT; i++) {
|
||||
for (i = 0; i < NCPU; i++) {
|
||||
if (CPU_ABSENT(i))
|
||||
continue;
|
||||
|
||||
mb_list_mbuf.ml_cntlst[i] = malloc(sizeof(struct mb_pcpu_list),
|
||||
M_MBUF, M_NOWAIT);
|
||||
mb_list_clust.ml_cntlst[i] = malloc(sizeof(struct mb_pcpu_list),
|
||||
@ -401,6 +415,7 @@ mb_init(void *dummy)
|
||||
mb_list_mbuf.ml_cntlst[i]->mb_cont.mc_lock =
|
||||
mb_list_clust.ml_cntlst[i]->mb_cont.mc_lock = &mbuf_pcpu[i];
|
||||
|
||||
mb_statpcpu[i].mb_active = 1;
|
||||
mb_list_mbuf.ml_cntlst[i]->mb_cont.mc_numowner =
|
||||
mb_list_clust.ml_cntlst[i]->mb_cont.mc_numowner = i;
|
||||
mb_list_mbuf.ml_cntlst[i]->mb_cont.mc_starved =
|
||||
@ -626,7 +641,9 @@ mb_alloc_wait(struct mb_lstmngr *mb_list)
|
||||
* Cycle all the PCPU containers. Increment starved counts if found
|
||||
* empty.
|
||||
*/
|
||||
for (i = 0; i < NCPU_PRESENT; i++) {
|
||||
for (i = 0; i < NCPU; i++) {
|
||||
if (CPU_ABSENT(i))
|
||||
continue;
|
||||
cnt_lst = MB_GET_PCPU_LIST_NUM(mb_list, i);
|
||||
MB_LOCK_CONT(cnt_lst);
|
||||
|
||||
|
@ -51,6 +51,7 @@ int boot_cpu_id;
|
||||
int
|
||||
cpu_mp_probe(void)
|
||||
{
|
||||
all_cpus = 1; /* needed for MB init code */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -216,6 +216,7 @@ struct mbpstat {
|
||||
u_long mb_mbpgs;
|
||||
u_long mb_clfree;
|
||||
u_long mb_clpgs;
|
||||
short mb_active;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -102,7 +102,7 @@ mbpr(u_long mbaddr, u_long mbtaddr, u_long nmbcaddr, u_long nmbufaddr,
|
||||
u_long mblimaddr, u_long cllimaddr, u_long cpusaddr, u_long pgsaddr,
|
||||
u_long mbpaddr)
|
||||
{
|
||||
int i, nmbufs, nmbclusters, ncpu, page_size, num_objs;
|
||||
int i, nmbufs, nmbclusters, page_size, num_objs;
|
||||
u_int mbuf_limit, clust_limit;
|
||||
u_long totspace, totnum, totfree;
|
||||
size_t mlen;
|
||||
@ -180,8 +180,6 @@ mbpr(u_long mbaddr, u_long mbtaddr, u_long nmbcaddr, u_long nmbufaddr,
|
||||
goto err;
|
||||
if (kread(cllimaddr, (char *)&clust_limit, sizeof(u_int)))
|
||||
goto err;
|
||||
if (kread(cpusaddr, (char *)&ncpu, sizeof(int)))
|
||||
goto err;
|
||||
if (kread(pgsaddr, (char *)&page_size, sizeof(int)))
|
||||
goto err;
|
||||
} else {
|
||||
@ -228,12 +226,6 @@ mbpr(u_long mbaddr, u_long mbtaddr, u_long nmbcaddr, u_long nmbufaddr,
|
||||
goto err;
|
||||
}
|
||||
mlen = sizeof(int);
|
||||
if (sysctlbyname("kern.smp.cpus", &ncpu, &mlen, NULL, 0) < 0 &&
|
||||
sysctlbyname("hw.ncpu", &ncpu, &mlen, NULL, 0) < 0) {
|
||||
warn("sysctl: retrieving number of cpus");
|
||||
goto err;
|
||||
}
|
||||
mlen = sizeof(int);
|
||||
if (sysctlbyname("hw.pagesize", &page_size, &mlen, NULL, 0)
|
||||
< 0) {
|
||||
warn("sysctl: retrieving hw.pagesize");
|
||||
@ -259,7 +251,9 @@ mbpr(u_long mbaddr, u_long mbtaddr, u_long nmbcaddr, u_long nmbufaddr,
|
||||
totnum = mbpstat[GENLST]->mb_mbpgs * MBPERPG;
|
||||
totfree = mbpstat[GENLST]->mb_mbfree;
|
||||
totspace = mbpstat[GENLST]->mb_mbpgs * page_size;
|
||||
for (i = 0; i < ncpu; i++) {
|
||||
for (i = 0; i < (num_objs - 1); i++) {
|
||||
if (mbpstat[i]->mb_active == 0)
|
||||
continue;
|
||||
printf("\tCPU #%d list:\t%lu/%lu (in use/in pool)\n", i,
|
||||
(mbpstat[i]->mb_mbpgs * MBPERPG - mbpstat[i]->mb_mbfree),
|
||||
(mbpstat[i]->mb_mbpgs * MBPERPG));
|
||||
@ -281,7 +275,9 @@ mbpr(u_long mbaddr, u_long mbtaddr, u_long nmbcaddr, u_long nmbufaddr,
|
||||
totnum = mbpstat[GENLST]->mb_clpgs * CLPERPG;
|
||||
totfree = mbpstat[GENLST]->mb_clfree;
|
||||
totspace = mbpstat[GENLST]->mb_clpgs * page_size;
|
||||
for (i = 0; i < ncpu; i++) {
|
||||
for (i = 0; i < (num_objs - 1); i++) {
|
||||
if (mbpstat[i]->mb_active == 0)
|
||||
continue;
|
||||
printf("\tCPU #%d list:\t%lu/%lu (in use/in pool)\n", i,
|
||||
(mbpstat[i]->mb_clpgs * CLPERPG - mbpstat[i]->mb_clfree),
|
||||
(mbpstat[i]->mb_clpgs * CLPERPG));
|
||||
|
@ -50,7 +50,7 @@ static const char rcsid[] =
|
||||
#include "extern.h"
|
||||
|
||||
static struct mbpstat **mbpstat;
|
||||
static int num_objs, ncpu;
|
||||
static int num_objs;
|
||||
#define GENLST (num_objs - 1)
|
||||
|
||||
/* XXX: mbtypes stats temporarily disabled. */
|
||||
@ -150,8 +150,11 @@ showmbufs()
|
||||
* Print total number of free mbufs.
|
||||
*/
|
||||
totfree = mbpstat[GENLST]->mb_mbfree;
|
||||
for (i = 0; i < ncpu; i++)
|
||||
for (i = 0; i < (num_objs - 1); i++) {
|
||||
if (mbpstat[i]->mb_active == 0)
|
||||
continue;
|
||||
totfree += mbpstat[i]->mb_mbfree;
|
||||
}
|
||||
j = 0; /* XXX */
|
||||
if (totfree > 0) {
|
||||
mvwprintw(wnd, 1+j, 0, "%-10.10s", "free");
|
||||
@ -189,12 +192,6 @@ initmbufs()
|
||||
}
|
||||
nmbtypes = mbtypeslen / sizeof(*m_mbtypes);
|
||||
#endif
|
||||
len = sizeof(int);
|
||||
if (sysctlbyname("kern.smp.cpus", &ncpu, &len, NULL, 0) < 0 &&
|
||||
sysctlbyname("hw.ncpu", &ncpu, &len, NULL, 0) < 0) {
|
||||
error("sysctl getting number of cpus");
|
||||
return 0;
|
||||
}
|
||||
if (sysctlbyname("kern.ipc.mb_statpcpu", NULL, &len, NULL, 0) < 0) {
|
||||
error("sysctl getting mbpstat total size failed");
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user