mirror of
https://git.FreeBSD.org/src.git
synced 2025-02-05 18:05:16 +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 u_int intrcnt_index = 0;
|
||||||
static struct mtx intr_table_lock;
|
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 struct pic piclist[MAX_PICS];
|
||||||
static u_int nvectors; /* Allocated vectors */
|
static u_int nvectors; /* Allocated vectors */
|
||||||
static u_int npics; /* PICs registered */
|
static u_int npics; /* PICs registered */
|
||||||
@ -130,10 +130,20 @@ static u_int nirqs = 0; /* Allocated IRQs. */
|
|||||||
#endif
|
#endif
|
||||||
static u_int stray_count;
|
static u_int stray_count;
|
||||||
|
|
||||||
u_long intrcnt[INTR_VECTORS];
|
u_long *intrcnt;
|
||||||
char intrnames[INTR_VECTORS * (MAXCOMLEN + 1)];
|
char *intrnames;
|
||||||
size_t sintrcnt = sizeof(intrcnt);
|
size_t sintrcnt = sizeof(intrcnt);
|
||||||
size_t sintrnames = sizeof(intrnames);
|
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;
|
device_t root_pic;
|
||||||
|
|
||||||
@ -141,6 +151,14 @@ device_t root_pic;
|
|||||||
static void *ipi_cookie;
|
static void *ipi_cookie;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
intrcnt_setname(const char *name, int index)
|
||||||
|
{
|
||||||
|
|
||||||
|
snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s",
|
||||||
|
MAXCOMLEN, name);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
intr_init(void *dummy __unused)
|
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);
|
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
|
#ifdef SMP
|
||||||
static void
|
static void
|
||||||
smp_intr_init(void *dummy __unused)
|
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);
|
SYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
|
||||||
intrcnt_setname(const char *name, int index)
|
|
||||||
{
|
|
||||||
|
|
||||||
snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s",
|
|
||||||
MAXCOMLEN, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
intrcnt_add(const char *name, u_long **countp)
|
intrcnt_add(const char *name, u_long **countp)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
idx = atomic_fetchadd_int(&intrcnt_index, 1);
|
idx = atomic_fetchadd_int(&intrcnt_index, 1);
|
||||||
KASSERT(idx < INTR_VECTORS, ("intrcnt_add: Interrupt counter index "
|
KASSERT(idx < nintrcnt, ("intrcnt_add: Interrupt counter index %d/%d"
|
||||||
"reached INTR_VECTORS"));
|
"reached nintrcnt : %d", intrcnt_index, idx, nintrcnt));
|
||||||
*countp = &intrcnt[idx];
|
*countp = &intrcnt[idx];
|
||||||
intrcnt_setname(name, idx);
|
intrcnt_setname(name, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void kdb_backtrace(void);
|
||||||
static struct powerpc_intr *
|
static struct powerpc_intr *
|
||||||
intr_lookup(u_int irq)
|
intr_lookup(u_int irq)
|
||||||
{
|
{
|
||||||
@ -224,7 +261,7 @@ intr_lookup(u_int irq)
|
|||||||
CPU_SETOF(0, &i->cpu);
|
CPU_SETOF(0, &i->cpu);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (vector = 0; vector < INTR_VECTORS && vector <= nvectors;
|
for (vector = 0; vector < num_io_irqs && vector <= nvectors;
|
||||||
vector++) {
|
vector++) {
|
||||||
iscan = powerpc_intrs[vector];
|
iscan = powerpc_intrs[vector];
|
||||||
if (iscan != NULL && iscan->irq == irq)
|
if (iscan != NULL && iscan->irq == irq)
|
||||||
|
@ -156,7 +156,7 @@ extern struct intr_event *clk_intr_event;
|
|||||||
extern void *vm_ih;
|
extern void *vm_ih;
|
||||||
|
|
||||||
/* Counts and names for statistics (defined in MD code). */
|
/* 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 u_long *intrcnt; /* counts for for each device and stray */
|
||||||
extern char *intrnames; /* string table containing device names */
|
extern char *intrnames; /* string table containing device names */
|
||||||
#else
|
#else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user