Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/subr_intr.c
Show First 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | SYSCTL_UINT(_machdep, OID_AUTO, nirq, CTLFLAG_RDTUN, &intr_nirq, 0, | ||||
"Number of IRQs"); | "Number of IRQs"); | ||||
/* Data for MI statistics reporting. */ | /* Data for MI statistics reporting. */ | ||||
u_long *intrcnt; | u_long *intrcnt; | ||||
char *intrnames; | char *intrnames; | ||||
size_t sintrcnt; | size_t sintrcnt; | ||||
size_t sintrnames; | size_t sintrnames; | ||||
static u_int intrcnt_index; | static u_int intrcnt_index; | ||||
#ifdef SMP | |||||
static u_int intrcnt_ipi_index; | |||||
#endif | |||||
static struct intr_irqsrc *intr_map_get_isrc(u_int res_id); | static struct intr_irqsrc *intr_map_get_isrc(u_int res_id); | ||||
static void intr_map_set_isrc(u_int res_id, struct intr_irqsrc *isrc); | static void intr_map_set_isrc(u_int res_id, struct intr_irqsrc *isrc); | ||||
static struct intr_map_data * intr_map_get_map_data(u_int res_id); | static struct intr_map_data * intr_map_get_map_data(u_int res_id); | ||||
static void intr_map_copy_map_data(u_int res_id, device_t *dev, intptr_t *xref, | static void intr_map_copy_map_data(u_int res_id, device_t *dev, intptr_t *xref, | ||||
struct intr_map_data **data); | struct intr_map_data **data); | ||||
/* | /* | ||||
* Interrupt framework initialization routine. | * Interrupt framework initialization routine. | ||||
*/ | */ | ||||
static void | static void | ||||
intr_irq_init(void *dummy __unused) | intr_irq_init(void *dummy __unused) | ||||
{ | { | ||||
u_int intrcnt_count; | u_int intrcnt_count; | ||||
int i; | |||||
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. | * - 2 counters for each I/O interrupt. | ||||
* - MAXCPU counters for each IPI counters for SMP. | * - MAXCPU counters for each IPI counters for SMP. | ||||
*/ | */ | ||||
intrcnt_count = intr_nirq * 2; | intrcnt_count = intr_nirq * 2; | ||||
#ifdef SMP | #ifdef SMP | ||||
intrcnt_ipi_index = intrcnt_count; | |||||
intrcnt_count += INTR_IPI_COUNT * MAXCPU; | intrcnt_count += INTR_IPI_COUNT * MAXCPU; | ||||
#endif | #endif | ||||
intrcnt = mallocarray(intrcnt_count, sizeof(u_long), M_INTRNG, | intrcnt = mallocarray(intrcnt_count, sizeof(u_long), M_INTRNG, | ||||
M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
for (i = 0; i < intr_nirq * 2; i += 2) | |||||
intrcnt[i] = i + 2; | |||||
intrnames = mallocarray(intrcnt_count, INTRNAME_LEN, M_INTRNG, | intrnames = mallocarray(intrcnt_count, INTRNAME_LEN, M_INTRNG, | ||||
M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
sintrcnt = intrcnt_count * sizeof(u_long); | sintrcnt = intrcnt_count * sizeof(u_long); | ||||
sintrnames = intrcnt_count * INTRNAME_LEN; | sintrnames = intrcnt_count * INTRNAME_LEN; | ||||
irq_sources = mallocarray(intr_nirq, sizeof(struct intr_irqsrc*), | irq_sources = mallocarray(intr_nirq, sizeof(struct intr_irqsrc*), | ||||
M_INTRNG, M_WAITOK | M_ZERO); | 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); | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Virtualization for interrupt source interrupt counters setup. | * Virtualization for interrupt source interrupt counters setup. | ||||
*/ | */ | ||||
static void | static void | ||||
isrc_setup_counters(struct intr_irqsrc *isrc) | isrc_setup_counters(struct intr_irqsrc *isrc) | ||||
{ | { | ||||
u_int index; | u_int index; | ||||
/* | while ((index = atomic_swap_int(&intrcnt_index, ~0)) == ~0); | ||||
* XXX - it does not work well with removable controllers and | if (index >= intr_nirq * 2) | ||||
* interrupt sources !!! | panic("%s: interrupt counters exhausted!", __func__); | ||||
*/ | atomic_store_int(&intrcnt_index, intrcnt[index]); | ||||
index = atomic_fetchadd_int(&intrcnt_index, 2); | |||||
isrc->isrc_index = index; | isrc->isrc_index = index; | ||||
isrc->isrc_count = &intrcnt[index]; | isrc->isrc_count = intrcnt + index; | ||||
intrcnt[index] = 0; | |||||
isrc_update_name(isrc, NULL); | isrc_update_name(isrc, NULL); | ||||
} | } | ||||
/* | /* | ||||
* Virtualization for interrupt source interrupt counters release. | * Virtualization for interrupt source interrupt counters release. | ||||
*/ | */ | ||||
static void | static void | ||||
isrc_release_counters(struct intr_irqsrc *isrc) | isrc_release_counters(struct intr_irqsrc *isrc) | ||||
{ | { | ||||
u_int index, prev; | |||||
panic("%s: not implemented", __func__); | index = isrc->isrc_index; | ||||
isrc->isrc_count = NULL; | |||||
intrcnt[index + 1] = 0; | |||||
isrc_update_name(isrc, NULL); | |||||
while ((prev = atomic_swap_int(&intrcnt_index, ~0)) == ~0); | |||||
intrcnt[index] = prev; | |||||
atomic_store_rel_int(&intrcnt_index, index); | |||||
} | } | ||||
#ifdef SMP | #ifdef SMP | ||||
/* | /* | ||||
* Virtualization for interrupt source IPI counters setup. | * Virtualization for interrupt source IPI counters setup. | ||||
*/ | */ | ||||
u_long * | u_long * | ||||
intr_ipi_setup_counters(const char *name) | intr_ipi_setup_counters(const char *name) | ||||
{ | { | ||||
u_int index, i; | u_int index, i; | ||||
char str[INTRNAME_LEN]; | char str[INTRNAME_LEN]; | ||||
index = atomic_fetchadd_int(&intrcnt_index, MAXCPU); | index = atomic_fetchadd_int(&intrcnt_ipi_index, MAXCPU); | ||||
for (i = 0; i < MAXCPU; i++) { | for (i = 0; i < MAXCPU; i++) { | ||||
snprintf(str, INTRNAME_LEN, "cpu%d:%s", i, name); | snprintf(str, INTRNAME_LEN, "cpu%d:%s", i, name); | ||||
intrcnt_setname(str, index + i); | intrcnt_setname(str, index + i); | ||||
} | } | ||||
return (&intrcnt[index]); | return (&intrcnt[index]); | ||||
} | } | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 1,417 Lines • Show Last 20 Lines |