make maximum interrupt number tunable on ARM, ARM64, MIPS, and RISC-V
Use a machdep.nirq tunable intead of compile-time constant NIRQ as a value for maximum number of interrupts. It allows keep a system footprint small by default with an option to increase the limit for large systems like server-grade ARM64 Reviewd by: mhorne Differential Revision: https://reviews.freebsd.org/D27844 Submitted by: Klara, Inc. Sponsored by: Ampere Computing
This commit is contained in:
parent
83bc72a04e
commit
248f0cabca
@ -122,7 +122,6 @@ ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
|
|||||||
ASSYM(MAXCOMLEN, MAXCOMLEN);
|
ASSYM(MAXCOMLEN, MAXCOMLEN);
|
||||||
ASSYM(MAXCPU, MAXCPU);
|
ASSYM(MAXCPU, MAXCPU);
|
||||||
ASSYM(_NCPUWORDS, _NCPUWORDS);
|
ASSYM(_NCPUWORDS, _NCPUWORDS);
|
||||||
ASSYM(NIRQ, NIRQ);
|
|
||||||
ASSYM(PCPU_SIZE, sizeof(struct pcpu));
|
ASSYM(PCPU_SIZE, sizeof(struct pcpu));
|
||||||
ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
|
ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
|
||||||
ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap));
|
ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap));
|
||||||
|
@ -310,10 +310,6 @@
|
|||||||
#define MV_GPIO_OUT_OPEN_DRAIN 0x2
|
#define MV_GPIO_OUT_OPEN_DRAIN 0x2
|
||||||
#define MV_GPIO_OUT_OPEN_SRC 0x4
|
#define MV_GPIO_OUT_OPEN_SRC 0x4
|
||||||
|
|
||||||
#define IS_GPIO_IRQ(irq) ((irq) >= NIRQ && (irq) < NIRQ + MV_GPIO_MAX_NPINS)
|
|
||||||
#define GPIO2IRQ(gpio) ((gpio) + NIRQ)
|
|
||||||
#define IRQ2GPIO(irq) ((irq) - NIRQ)
|
|
||||||
|
|
||||||
#if defined(SOC_MV_ORION)
|
#if defined(SOC_MV_ORION)
|
||||||
#define SAMPLE_AT_RESET 0x10
|
#define SAMPLE_AT_RESET 0x10
|
||||||
#elif defined(SOC_MV_KIRKWOOD)
|
#elif defined(SOC_MV_KIRKWOOD)
|
||||||
|
@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
#include <sys/smp.h>
|
#include <sys/smp.h>
|
||||||
|
#include <sys/interrupt.h>
|
||||||
|
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
#include <vm/pmap.h>
|
#include <vm/pmap.h>
|
||||||
@ -388,7 +389,7 @@ gic_v3_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
|
|||||||
|
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case GICV3_IVAR_NIRQS:
|
case GICV3_IVAR_NIRQS:
|
||||||
*result = (NIRQ - sc->gic_nirqs) / sc->gic_nchildren;
|
*result = (intr_nirq - sc->gic_nirqs) / sc->gic_nchildren;
|
||||||
return (0);
|
return (0);
|
||||||
case GICV3_IVAR_REDIST:
|
case GICV3_IVAR_REDIST:
|
||||||
*result = (uintptr_t)sc->gic_redists.pcpu[PCPU_GET(cpuid)];
|
*result = (uintptr_t)sc->gic_redists.pcpu[PCPU_GET(cpuid)];
|
||||||
|
@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/rman.h>
|
#include <sys/rman.h>
|
||||||
#include <sys/sched.h>
|
#include <sys/sched.h>
|
||||||
#include <sys/smp.h>
|
#include <sys/smp.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
#include <sys/vmmeter.h>
|
#include <sys/vmmeter.h>
|
||||||
#ifdef HWPMC_HOOKS
|
#ifdef HWPMC_HOOKS
|
||||||
#include <sys/pmckern.h>
|
#include <sys/pmckern.h>
|
||||||
@ -131,7 +132,7 @@ static struct intr_pic *pic_lookup(device_t dev, intptr_t xref, int flags);
|
|||||||
|
|
||||||
/* Interrupt source definition. */
|
/* Interrupt source definition. */
|
||||||
static struct mtx isrc_table_lock;
|
static struct mtx isrc_table_lock;
|
||||||
static struct intr_irqsrc *irq_sources[NIRQ];
|
static struct intr_irqsrc **irq_sources;
|
||||||
u_int irq_next_free;
|
u_int irq_next_free;
|
||||||
|
|
||||||
#ifdef SMP
|
#ifdef SMP
|
||||||
@ -142,21 +143,15 @@ static bool irq_assign_cpu = false;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
int intr_nirq = NIRQ;
|
||||||
* - 2 counters for each I/O interrupt.
|
SYSCTL_UINT(_machdep, OID_AUTO, nirq, CTLFLAG_RDTUN, &intr_nirq, 0,
|
||||||
* - MAXCPU counters for each IPI counters for SMP.
|
"Number of IRQs");
|
||||||
*/
|
|
||||||
#ifdef SMP
|
|
||||||
#define INTRCNT_COUNT (NIRQ * 2 + INTR_IPI_COUNT * MAXCPU)
|
|
||||||
#else
|
|
||||||
#define INTRCNT_COUNT (NIRQ * 2)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Data for MI statistics reporting. */
|
/* Data for MI statistics reporting. */
|
||||||
u_long intrcnt[INTRCNT_COUNT];
|
u_long *intrcnt;
|
||||||
char intrnames[INTRCNT_COUNT * INTRNAME_LEN];
|
char *intrnames;
|
||||||
size_t sintrcnt = sizeof(intrcnt);
|
size_t sintrcnt;
|
||||||
size_t sintrnames = sizeof(intrnames);
|
size_t sintrnames;
|
||||||
static u_int intrcnt_index;
|
static u_int intrcnt_index;
|
||||||
|
|
||||||
static struct intr_irqsrc *intr_map_get_isrc(u_int res_id);
|
static struct intr_irqsrc *intr_map_get_isrc(u_int res_id);
|
||||||
@ -171,11 +166,30 @@ static void intr_map_copy_map_data(u_int res_id, device_t *dev, intptr_t *xref,
|
|||||||
static void
|
static void
|
||||||
intr_irq_init(void *dummy __unused)
|
intr_irq_init(void *dummy __unused)
|
||||||
{
|
{
|
||||||
|
int intrcnt_count;
|
||||||
|
|
||||||
SLIST_INIT(&pic_list);
|
SLIST_INIT(&pic_list);
|
||||||
mtx_init(&pic_list_lock, "intr pic list", NULL, MTX_DEF);
|
mtx_init(&pic_list_lock, "intr pic list", NULL, MTX_DEF);
|
||||||
|
|
||||||
mtx_init(&isrc_table_lock, "intr isrc table", NULL, MTX_DEF);
|
mtx_init(&isrc_table_lock, "intr isrc table", NULL, MTX_DEF);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* - 2 counters for each I/O interrupt.
|
||||||
|
* - MAXCPU counters for each IPI counters for SMP.
|
||||||
|
*/
|
||||||
|
intrcnt_count = intr_nirq * 2;
|
||||||
|
#ifdef SMP
|
||||||
|
intrcnt_count += INTR_IPI_COUNT * MAXCPU;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
intrcnt = mallocarray(intrcnt_count, sizeof(u_long), M_INTRNG,
|
||||||
|
M_WAITOK | M_ZERO);
|
||||||
|
intrnames = mallocarray(intrcnt_count, INTRNAME_LEN, M_INTRNG,
|
||||||
|
M_WAITOK | M_ZERO);
|
||||||
|
sintrcnt = intrcnt_count * sizeof(u_long);
|
||||||
|
sintrnames = intrcnt_count * INTRNAME_LEN;
|
||||||
|
irq_sources = mallocarray(intr_nirq, sizeof(struct intr_irqsrc*),
|
||||||
|
M_INTRNG, M_WAITOK | M_ZERO);
|
||||||
}
|
}
|
||||||
SYSINIT(intr_irq_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_irq_init, NULL);
|
SYSINIT(intr_irq_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_irq_init, NULL);
|
||||||
|
|
||||||
@ -391,7 +405,7 @@ isrc_alloc_irq(struct intr_irqsrc *isrc)
|
|||||||
|
|
||||||
mtx_assert(&isrc_table_lock, MA_OWNED);
|
mtx_assert(&isrc_table_lock, MA_OWNED);
|
||||||
|
|
||||||
maxirqs = nitems(irq_sources);
|
maxirqs = intr_nirq;
|
||||||
if (irq_next_free >= maxirqs)
|
if (irq_next_free >= maxirqs)
|
||||||
return (ENOSPC);
|
return (ENOSPC);
|
||||||
|
|
||||||
@ -426,7 +440,7 @@ isrc_free_irq(struct intr_irqsrc *isrc)
|
|||||||
|
|
||||||
mtx_assert(&isrc_table_lock, MA_OWNED);
|
mtx_assert(&isrc_table_lock, MA_OWNED);
|
||||||
|
|
||||||
if (isrc->isrc_irq >= nitems(irq_sources))
|
if (isrc->isrc_irq >= intr_nirq)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
if (irq_sources[isrc->isrc_irq] != isrc)
|
if (irq_sources[isrc->isrc_irq] != isrc)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
@ -1229,7 +1243,7 @@ intr_irq_shuffle(void *arg __unused)
|
|||||||
|
|
||||||
mtx_lock(&isrc_table_lock);
|
mtx_lock(&isrc_table_lock);
|
||||||
irq_assign_cpu = true;
|
irq_assign_cpu = true;
|
||||||
for (i = 0; i < NIRQ; i++) {
|
for (i = 0; i < intr_nirq; i++) {
|
||||||
isrc = irq_sources[i];
|
isrc = irq_sources[i];
|
||||||
if (isrc == NULL || isrc->isrc_handlers == 0 ||
|
if (isrc == NULL || isrc->isrc_handlers == 0 ||
|
||||||
isrc->isrc_flags & (INTR_ISRCF_PPI | INTR_ISRCF_IPI))
|
isrc->isrc_flags & (INTR_ISRCF_PPI | INTR_ISRCF_IPI))
|
||||||
@ -1529,7 +1543,7 @@ DB_SHOW_COMMAND(irqs, db_show_irqs)
|
|||||||
u_long num;
|
u_long num;
|
||||||
struct intr_irqsrc *isrc;
|
struct intr_irqsrc *isrc;
|
||||||
|
|
||||||
for (irqsum = 0, i = 0; i < NIRQ; i++) {
|
for (irqsum = 0, i = 0; i < intr_nirq; i++) {
|
||||||
isrc = irq_sources[i];
|
isrc = irq_sources[i];
|
||||||
if (isrc == NULL)
|
if (isrc == NULL)
|
||||||
continue;
|
continue;
|
||||||
@ -1561,8 +1575,8 @@ struct intr_map_entry
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* XXX Convert irq_map[] to dynamicaly expandable one. */
|
/* XXX Convert irq_map[] to dynamicaly expandable one. */
|
||||||
static struct intr_map_entry *irq_map[2 * NIRQ];
|
static struct intr_map_entry **irq_map;
|
||||||
static int irq_map_count = nitems(irq_map);
|
static int irq_map_count;
|
||||||
static int irq_map_first_free_idx;
|
static int irq_map_first_free_idx;
|
||||||
static struct mtx irq_map_lock;
|
static struct mtx irq_map_lock;
|
||||||
|
|
||||||
@ -1712,5 +1726,9 @@ intr_map_init(void *dummy __unused)
|
|||||||
{
|
{
|
||||||
|
|
||||||
mtx_init(&irq_map_lock, "intr map table", NULL, MTX_DEF);
|
mtx_init(&irq_map_lock, "intr map table", NULL, MTX_DEF);
|
||||||
|
|
||||||
|
irq_map_count = 2 * intr_nirq;
|
||||||
|
irq_map = mallocarray(irq_map_count, sizeof(struct intr_map_entry*),
|
||||||
|
M_INTRNG, M_WAITOK | M_ZERO);
|
||||||
}
|
}
|
||||||
SYSINIT(intr_map_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_map_init, NULL);
|
SYSINIT(intr_map_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_map_init, NULL);
|
||||||
|
@ -77,7 +77,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#endif /* NEXUS_DEBUG */
|
#endif /* NEXUS_DEBUG */
|
||||||
|
|
||||||
#ifdef INTRNG
|
#ifdef INTRNG
|
||||||
#define NUM_MIPS_IRQS NIRQ /* Any INTRNG-mapped IRQ */
|
#define NUM_MIPS_IRQS intr_nirq /* Any INTRNG-mapped IRQ */
|
||||||
#else
|
#else
|
||||||
#define NUM_MIPS_IRQS 6 /* HW IRQs only */
|
#define NUM_MIPS_IRQS 6 /* HW IRQs only */
|
||||||
#endif
|
#endif
|
||||||
|
@ -157,13 +157,8 @@ extern struct intr_event *tty_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__) || 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
|
|
||||||
extern u_long intrcnt[]; /* counts for for each device and stray */
|
|
||||||
extern char intrnames[]; /* string table containing device names */
|
|
||||||
#endif
|
|
||||||
extern size_t sintrcnt; /* size of intrcnt table */
|
extern size_t sintrcnt; /* size of intrcnt table */
|
||||||
extern size_t sintrnames; /* size of intrnames table */
|
extern size_t sintrnames; /* size of intrnames table */
|
||||||
|
|
||||||
|
@ -164,4 +164,7 @@ intr_ipi_increment_count(u_long *counter, u_int cpu)
|
|||||||
u_long * intr_ipi_setup_counters(const char *name);
|
u_long * intr_ipi_setup_counters(const char *name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern int intr_nirq; /* number of IRQs on intrng platforms */
|
||||||
|
|
||||||
#endif /* _SYS_INTR_H */
|
#endif /* _SYS_INTR_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user