1
0
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:
Justin Hibbits 2019-03-02 01:51:41 +00:00
parent 7d93ab5e35
commit 51244b1e46
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=344716
2 changed files with 52 additions and 15 deletions

View File

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

View File

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