Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/powerpc/intr_machdep.c
Show First 20 Lines • Show All 166 Lines • ▼ Show 20 Lines | |||||
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 | static void | ||||
intr_init_sources(void *arg __unused) | intr_init_sources(void *arg __unused) | ||||
{ | { | ||||
powerpc_intrs = mallocarray(num_io_irqs, sizeof(*powerpc_intrs), | powerpc_intrs = mallocarray(num_io_irqs, sizeof(*powerpc_intrs), | ||||
M_INTR, M_WAITOK | M_ZERO); | M_INTR, M_WAITOK | M_ZERO); | ||||
nintrcnt = 1 + num_io_irqs * 2 + mp_ncpus * 2; | nintrcnt = 1 + num_io_irqs * 2 + mp_ncpus * 2; | ||||
ehem_freebsd_m5p.com: I'm rather suspicious about this computation for the table size. I'm unfamiliar with how the… | |||||
#ifdef COUNT_IPIS | #ifdef COUNT_IPIS | ||||
if (mp_ncpus > 1) | if (mp_ncpus > 1) | ||||
nintrcnt += 8 * mp_ncpus; | nintrcnt += 8 * mp_ncpus; | ||||
#endif | #endif | ||||
intrcnt = mallocarray(nintrcnt, sizeof(u_long), M_INTR, M_WAITOK | | intrcnt = mallocarray(nintrcnt, sizeof(u_long), M_INTR, M_WAITOK | | ||||
M_ZERO); | M_ZERO); | ||||
intrnames = mallocarray(nintrcnt, INTRNAME_LEN, M_INTR, M_WAITOK | | intrnames = mallocarray(nintrcnt, INTRNAME_LEN, M_INTR, M_WAITOK | | ||||
M_ZERO); | M_ZERO); | ||||
Done Inline Actionsintrnames = mallocarray(); clearly this is interpreting "intrnames" as an array of fixed-length strings. This matches with intrcnt_setname() using intrnames + (MAXCOMLEN + 1) * index, just above. ehem_freebsd_m5p.com: `intrnames = mallocarray();` clearly this is interpreting "intrnames" as an array of fixed… | |||||
intrcnt_setname("???", 0); | intrcnt_setname("???", 0); | ||||
intrcnt_index = 1; | intrcnt_index = 1; | ||||
Done Inline ActionsThis was clearly copied from x86. I've got no idea what purpose this questionable interrupt served and when. Since there is no documentation, I suspect it is unused now. ehem_freebsd_m5p.com: This was clearly copied from x86. I've got no idea what purpose this questionable interrupt… | |||||
} | } | ||||
/* | /* | ||||
* This needs to happen before SI_SUB_CPU | * This needs to happen before SI_SUB_CPU | ||||
*/ | */ | ||||
SYSINIT(intr_init_sources, SI_SUB_KLD, SI_ORDER_ANY, intr_init_sources, NULL); | SYSINIT(intr_init_sources, SI_SUB_KLD, SI_ORDER_ANY, intr_init_sources, NULL); | ||||
#ifdef SMP | #ifdef SMP | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | if (iscan != NULL && iscan->irq == irq) | ||||
break; | break; | ||||
if (iscan == NULL && i->vector == -1) | if (iscan == NULL && i->vector == -1) | ||||
i->vector = vector; | i->vector = vector; | ||||
iscan = NULL; | iscan = NULL; | ||||
} | } | ||||
if (iscan == NULL && i->vector != -1) { | if (iscan == NULL && i->vector != -1) { | ||||
powerpc_intrs[i->vector] = i; | powerpc_intrs[i->vector] = i; | ||||
i->cntindex = atomic_fetchadd_int(&intrcnt_index, 1); | i->cntindex = nintrcnt - 1; | ||||
i->cntp = &intrcnt[i->cntindex]; | i->cntp = &intrcnt[i->cntindex]; | ||||
sprintf(intrname, "irq%u:", i->irq); | sprintf(intrname, "irq%u:", i->irq); | ||||
intrcnt_setname(intrname, i->cntindex); | intrcnt_setname(intrname, i->cntindex); | ||||
nvectors++; | nvectors++; | ||||
} | } | ||||
mtx_unlock(&intr_table_lock); | mtx_unlock(&intr_table_lock); | ||||
if (iscan != NULL || i->vector == -1) { | if (iscan != NULL || i->vector == -1) { | ||||
▲ Show 20 Lines • Show All 412 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Sysctls used by systat and others: hw.intrnames and hw.intrcnt. | * Sysctls used by systat and others: hw.intrnames and hw.intrcnt. | ||||
*/ | */ | ||||
static int | static int | ||||
sysctl_intrnames(SYSCTL_HANDLER_ARGS) | sysctl_intrnames(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
return (sysctl_handle_opaque(oidp, intrnames, | int error; | ||||
intrcnt_index * INTRNAME_LEN, req)); | |||||
error = sysctl_handle_opaque(oidp, intrnames, | |||||
intrcnt_index * INTRNAME_LEN, req); | |||||
if (error != 0) | |||||
return (error); | |||||
return (intr_event_sysctl_intrnames(oidp, arg1, arg2, req)); | |||||
} | } | ||||
SYSCTL_PROC(_hw, OID_AUTO, intrnames, | SYSCTL_PROC(_hw, OID_AUTO, intrnames, | ||||
CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, | CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, | ||||
sysctl_intrnames, | sysctl_intrnames, | ||||
"", "Interrupt Names"); | "", "Interrupt Names"); | ||||
static int | static int | ||||
sysctl_intrcnt(SYSCTL_HANDLER_ARGS) | sysctl_intrcnt(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
int error; | |||||
#ifdef SCTL_MASK32 | #ifdef SCTL_MASK32 | ||||
uint32_t *intrcnt32; | uint32_t *intrcnt32; | ||||
unsigned i; | unsigned i; | ||||
int error; | |||||
if (req->flags & SCTL_MASK32) { | if (req->flags & SCTL_MASK32) { | ||||
if (!req->oldptr) | if (!req->oldptr) | ||||
return (sysctl_handle_opaque(oidp, NULL, | return (sysctl_handle_opaque(oidp, NULL, | ||||
intrcnt_index * sizeof(uint32_t), req)); | intrcnt_index * sizeof(uint32_t), req)); | ||||
intrcnt32 = malloc(intrcnt_index * sizeof(uint32_t), M_TEMP, | intrcnt32 = malloc(intrcnt_index * sizeof(uint32_t), M_TEMP, | ||||
M_NOWAIT); | M_NOWAIT); | ||||
if (intrcnt32 == NULL) | if (intrcnt32 == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
for (i = 0; i < intrcnt_index; i++) | for (i = 0; i < intrcnt_index; i++) | ||||
intrcnt32[i] = intrcnt[i]; | intrcnt32[i] = intrcnt[i]; | ||||
error = sysctl_handle_opaque(oidp, intrcnt32, | error = sysctl_handle_opaque(oidp, intrcnt32, | ||||
intrcnt_index * sizeof(uint32_t), req); | intrcnt_index * sizeof(uint32_t), req); | ||||
free(intrcnt32, M_TEMP); | free(intrcnt32, M_TEMP); | ||||
return (error); | } else | ||||
} | |||||
#endif | #endif | ||||
return (sysctl_handle_opaque(oidp, intrcnt, | error = sysctl_handle_opaque(oidp, intrcnt, | ||||
intrcnt_index * sizeof(u_long), req)); | intrcnt_index * sizeof(u_long), req); | ||||
return (error == 0 ? intr_event_sysctl_intrcnt(oidp, arg1, arg2, req) : | |||||
error); | |||||
} | } | ||||
SYSCTL_PROC(_hw, OID_AUTO, intrcnt, | SYSCTL_PROC(_hw, OID_AUTO, intrcnt, | ||||
CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, | CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, | ||||
sysctl_intrcnt, | sysctl_intrcnt, | ||||
"", "Interrupt Counts"); | "", "Interrupt Counts"); | ||||
#ifdef DDB | #ifdef DDB | ||||
/* | /* | ||||
* DDB command to dump the interrupt statistics. | * DDB command to dump the IPI interrupt statistics. | ||||
*/ | */ | ||||
DB_SHOW_COMMAND_FLAGS(intrcnt, db_show_intrcnt, DB_CMD_MEMSAFE) | DB_SHOW_COMMAND_FLAGS(ipicnt, db_show_ipicnt, DB_CMD_MEMSAFE) | ||||
{ | { | ||||
u_int i; | u_int i; | ||||
for (i = 0; i < intrcnt_index && !db_pager_quit; ++i) | for (i = 0; i < intrcnt_index && !db_pager_quit; ++i) | ||||
if (intrcnt[i] != 0) | if (intrcnt[i] != 0) | ||||
db_printf("%s\t%lu\n", intrnames + i * INTRNAME_LEN, | db_printf("%s\t%lu\n", intrnames + i * INTRNAME_LEN, | ||||
intrcnt[i]); | intrcnt[i]); | ||||
} | } | ||||
#endif | #endif |
I'm rather suspicious about this computation for the table size. I'm unfamiliar with how the interrupt counters work on PowerPC, but based on how INTRNG behaves this is way too few.