mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-27 16:39:08 +00:00
powerpc: Scale intrcnt by mp_ncpus
On very large powerpc64 systems (2x22x4 power9) it's very easy to run out of available IRQs and crash the system at boot. Scale the count by mp_ncpus, similar to x86, so this doesn't happen. Further work can be done in the future to scale the I/O IRQs as well, but that's left for the future. Submitted by: mmacy MFC after: 3 weeks
This commit is contained in:
parent
7d93ab5e35
commit
51244b1e46
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=344716
@ -119,7 +119,7 @@ struct pic {
|
||||
|
||||
static u_int intrcnt_index = 0;
|
||||
static struct mtx intr_table_lock;
|
||||
static struct powerpc_intr *powerpc_intrs[INTR_VECTORS];
|
||||
static struct powerpc_intr **powerpc_intrs;
|
||||
static struct pic piclist[MAX_PICS];
|
||||
static u_int nvectors; /* Allocated vectors */
|
||||
static u_int npics; /* PICs registered */
|
||||
@ -130,10 +130,20 @@ static u_int nirqs = 0; /* Allocated IRQs. */
|
||||
#endif
|
||||
static u_int stray_count;
|
||||
|
||||
u_long intrcnt[INTR_VECTORS];
|
||||
char intrnames[INTR_VECTORS * (MAXCOMLEN + 1)];
|
||||
u_long *intrcnt;
|
||||
char *intrnames;
|
||||
size_t sintrcnt = sizeof(intrcnt);
|
||||
size_t sintrnames = sizeof(intrnames);
|
||||
int nintrcnt;
|
||||
|
||||
/*
|
||||
* Just to start
|
||||
*/
|
||||
#ifdef __powerpc64__
|
||||
u_int num_io_irqs = 768;
|
||||
#else
|
||||
u_int num_io_irqs = 256;
|
||||
#endif
|
||||
|
||||
device_t root_pic;
|
||||
|
||||
@ -141,6 +151,14 @@ device_t root_pic;
|
||||
static void *ipi_cookie;
|
||||
#endif
|
||||
|
||||
static void
|
||||
intrcnt_setname(const char *name, int index)
|
||||
{
|
||||
|
||||
snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s",
|
||||
MAXCOMLEN, name);
|
||||
}
|
||||
|
||||
static void
|
||||
intr_init(void *dummy __unused)
|
||||
{
|
||||
@ -149,6 +167,32 @@ intr_init(void *dummy __unused)
|
||||
}
|
||||
SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL);
|
||||
|
||||
static void
|
||||
intr_init_sources(void *arg __unused)
|
||||
{
|
||||
|
||||
powerpc_intrs = mallocarray(num_io_irqs, sizeof(*powerpc_intrs),
|
||||
M_INTR, M_WAITOK | M_ZERO);
|
||||
nintrcnt = 1 + num_io_irqs * 2 + mp_ncpus * 2;
|
||||
#ifdef COUNT_IPIS
|
||||
if (mp_ncpus > 1)
|
||||
nintrcnt += 8 * mp_ncpus;
|
||||
#endif
|
||||
intrcnt = mallocarray(nintrcnt, sizeof(u_long), M_INTR, M_WAITOK |
|
||||
M_ZERO);
|
||||
intrnames = mallocarray(nintrcnt, MAXCOMLEN + 1, M_INTR, M_WAITOK |
|
||||
M_ZERO);
|
||||
sintrcnt = nintrcnt * sizeof(u_long);
|
||||
sintrnames = nintrcnt * (MAXCOMLEN + 1);
|
||||
|
||||
intrcnt_setname("???", 0);
|
||||
intrcnt_index = 1;
|
||||
}
|
||||
/*
|
||||
* This needs to happen before SI_SUB_CPU
|
||||
*/
|
||||
SYSINIT(intr_init_sources, SI_SUB_KLD, SI_ORDER_ANY, intr_init_sources, NULL);
|
||||
|
||||
#ifdef SMP
|
||||
static void
|
||||
smp_intr_init(void *dummy __unused)
|
||||
@ -165,26 +209,19 @@ smp_intr_init(void *dummy __unused)
|
||||
SYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL);
|
||||
#endif
|
||||
|
||||
static void
|
||||
intrcnt_setname(const char *name, int index)
|
||||
{
|
||||
|
||||
snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s",
|
||||
MAXCOMLEN, name);
|
||||
}
|
||||
|
||||
void
|
||||
intrcnt_add(const char *name, u_long **countp)
|
||||
{
|
||||
int idx;
|
||||
|
||||
idx = atomic_fetchadd_int(&intrcnt_index, 1);
|
||||
KASSERT(idx < INTR_VECTORS, ("intrcnt_add: Interrupt counter index "
|
||||
"reached INTR_VECTORS"));
|
||||
KASSERT(idx < nintrcnt, ("intrcnt_add: Interrupt counter index %d/%d"
|
||||
"reached nintrcnt : %d", intrcnt_index, idx, nintrcnt));
|
||||
*countp = &intrcnt[idx];
|
||||
intrcnt_setname(name, idx);
|
||||
}
|
||||
|
||||
extern void kdb_backtrace(void);
|
||||
static struct powerpc_intr *
|
||||
intr_lookup(u_int irq)
|
||||
{
|
||||
@ -224,7 +261,7 @@ intr_lookup(u_int irq)
|
||||
CPU_SETOF(0, &i->cpu);
|
||||
#endif
|
||||
|
||||
for (vector = 0; vector < INTR_VECTORS && vector <= nvectors;
|
||||
for (vector = 0; vector < num_io_irqs && vector <= nvectors;
|
||||
vector++) {
|
||||
iscan = powerpc_intrs[vector];
|
||||
if (iscan != NULL && iscan->irq == irq)
|
||||
|
@ -156,7 +156,7 @@ extern struct intr_event *clk_intr_event;
|
||||
extern void *vm_ih;
|
||||
|
||||
/* Counts and names for statistics (defined in MD code). */
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
#if defined(__amd64__) || defined(__i386__) || defined(__powerpc__)
|
||||
extern u_long *intrcnt; /* counts for for each device and stray */
|
||||
extern char *intrnames; /* string table containing device names */
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user