- 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:
Bosko Milekic 2001-07-26 18:47:46 +00:00
parent 99b3dc42ad
commit 49f854f926
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=80399
13 changed files with 80 additions and 48 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -51,6 +51,7 @@ int boot_cpu_id;
int
cpu_mp_probe(void)
{
all_cpus = 1; /* needed for MB init code */
return 0;
}

View File

@ -216,6 +216,7 @@ struct mbpstat {
u_long mb_mbpgs;
u_long mb_clfree;
u_long mb_clpgs;
short mb_active;
};
/*

View File

@ -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));

View File

@ -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;