Page MenuHomeFreeBSD

D36610.id116816.diff
No OneTemporary

D36610.id116816.diff

diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c
--- a/sys/kern/kern_intr.c
+++ b/sys/kern/kern_intr.c
@@ -1642,3 +1642,92 @@
}
SYSINIT(start_softintr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softintr,
NULL);
+
+/*
+ * Sysctls used by systat and others: hw.intrnames and hw.intrcnt.
+ * The data for this machine independent.
+ */
+int
+intr_event_sysctl_intrnames(SYSCTL_HANDLER_ARGS)
+{
+ struct intr_event *ie;
+ u_int len;
+ const char straystr[] = "stray ";
+ int error;
+
+ sx_slock(&event_lock);
+ TAILQ_FOREACH(ie, &event_list, ie_list) {
+ len = strnlen(ie->ie_fullname, sizeof(ie->ie_fullname)) + 1;
+ error = SYSCTL_OUT(req, ie->ie_fullname, len);
+ if (error != 0)
+ goto out;
+
+ error = SYSCTL_OUT(req, straystr, sizeof(straystr) - 1);
+ if (error != 0)
+ goto out;
+ error = SYSCTL_OUT(req, ie->ie_fullname, len);
+ if (error != 0)
+ goto out;
+ }
+out:
+ sx_sunlock(&event_lock);
+ return (error);
+}
+
+int
+intr_event_sysctl_intrcnt(SYSCTL_HANDLER_ARGS)
+{
+ struct intr_event *ie;
+ int error = 0;
+ int sz = sizeof(ie->ie_intrcnt);
+ u_long val;
+ void *arg = &val;
+#ifdef SCTL_MASK32
+ uint32_t val32;
+
+ if (req->flags & SCTL_MASK32) {
+ sz = sizeof(val32);
+ arg = &val32;
+ }
+#endif
+
+ sx_slock(&event_lock);
+ TAILQ_FOREACH(ie, &event_list, ie_list) {
+#ifdef SCTL_MASK32
+ val32 =
+#endif
+ val = atomic_load_long(&ie->ie_intrcnt);
+ if (val == 0)
+ continue;
+ error = SYSCTL_OUT(req, arg, sz);
+ if (error != 0)
+ goto out;
+
+#ifdef SCTL_MASK32
+ val32 =
+#endif
+ val = atomic_load_long(&ie->ie_stray);
+ error = SYSCTL_OUT(req, arg, sz);
+ if (error != 0)
+ goto out;
+ }
+out:
+ sx_sunlock(&event_lock);
+ return (error);
+}
+
+#ifdef DDB
+/*
+ * DDB command to dump the interrupt statistics.
+ */
+DB_SHOW_COMMAND_FLAGS(intrcnt, db_show_intrcnt, DB_CMD_MEMSAFE)
+{
+ struct intr_event *ie;
+
+ for (ie = TAILQ_FIRST(&event_list); ie && !db_pager_quit;
+ ie = TAILQ_NEXT(ie, ie_list))
+ if (ie->ie_intrcnt != 0)
+ db_printf("%s\t%lu\nstray %s\t%lu\n", ie->ie_fullname,
+ ie->ie_intrcnt, ie->ie_fullname, ie->ie_stray);
+}
+#endif
diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c
--- a/sys/kern/subr_intr.c
+++ b/sys/kern/subr_intr.c
@@ -269,10 +269,7 @@
* XXX - it does not work well with removable controllers and
* interrupt sources !!!
*/
- index = atomic_fetchadd_int(&intrcnt_index, 2);
- if (index + 2 > intrcnt_count)
- panic("overflowed interrupt name/counter table (index=%u)",
- index);
+ index = intrcnt_count - 2;
isrc->isrc_index = index;
isrc->isrc_count = &intrcnt[index];
isrc_update_name(isrc, NULL);
@@ -1560,7 +1557,7 @@
if (isrc == NULL)
continue;
- num = isrc->isrc_count != NULL ? isrc->isrc_count[0] : 0;
+ num = isrc->isrc_event != NULL ? isrc->isrc_event->ie_intrcnt : 0;
db_printf("irq%-3u <%s>: cpu %02lx%s cnt %lu\n", i,
isrc->isrc_name, isrc->isrc_cpu.__bits[0],
isrc->isrc_flags & INTR_ISRCF_BOUND ? " (bound)" : "", num);
@@ -1751,8 +1748,14 @@
static int
sysctl_intrnames(SYSCTL_HANDLER_ARGS)
{
- return (sysctl_handle_opaque(oidp, intrnames,
- intrcnt_index * INTRNAME_LEN, req));
+ int error;
+
+ 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,
@@ -1763,10 +1766,10 @@
static int
sysctl_intrcnt(SYSCTL_HANDLER_ARGS)
{
+ int error;
#ifdef SCTL_MASK32
uint32_t *intrcnt32;
unsigned i;
- int error;
if (req->flags & SCTL_MASK32) {
if (!req->oldptr)
@@ -1781,11 +1784,13 @@
error = sysctl_handle_opaque(oidp, intrcnt32,
intrcnt_index * sizeof(uint32_t), req);
free(intrcnt32, M_TEMP);
- return (error);
- }
+ } else
#endif
- return (sysctl_handle_opaque(oidp, intrcnt,
- intrcnt_index * sizeof(u_long), req));
+ error = sysctl_handle_opaque(oidp, intrcnt,
+ intrcnt_index * sizeof(u_long), req);
+
+ return (error == 0 ? intr_event_sysctl_intrcnt(oidp, arg1, arg2, req) :
+ error);
}
SYSCTL_PROC(_hw, OID_AUTO, intrcnt,
@@ -1795,9 +1800,9 @@
#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;
diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c
--- a/sys/powerpc/powerpc/intr_machdep.c
+++ b/sys/powerpc/powerpc/intr_machdep.c
@@ -270,7 +270,7 @@
if (iscan == NULL && i->vector != -1) {
powerpc_intrs[i->vector] = i;
- i->cntindex = atomic_fetchadd_int(&intrcnt_index, 1);
+ i->cntindex = nintrcnt - 1;
i->cntp = &intrcnt[i->cntindex];
sprintf(intrname, "irq%u:", i->irq);
intrcnt_setname(intrname, i->cntindex);
@@ -699,8 +699,14 @@
static int
sysctl_intrnames(SYSCTL_HANDLER_ARGS)
{
- return (sysctl_handle_opaque(oidp, intrnames,
- intrcnt_index * INTRNAME_LEN, req));
+ int error;
+
+ 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,
@@ -711,10 +717,10 @@
static int
sysctl_intrcnt(SYSCTL_HANDLER_ARGS)
{
+ int error;
#ifdef SCTL_MASK32
uint32_t *intrcnt32;
unsigned i;
- int error;
if (req->flags & SCTL_MASK32) {
if (!req->oldptr)
@@ -729,11 +735,13 @@
error = sysctl_handle_opaque(oidp, intrcnt32,
intrcnt_index * sizeof(uint32_t), req);
free(intrcnt32, M_TEMP);
- return (error);
- }
+ } else
#endif
- return (sysctl_handle_opaque(oidp, intrcnt,
- intrcnt_index * sizeof(u_long), req));
+ error = sysctl_handle_opaque(oidp, intrcnt,
+ intrcnt_index * sizeof(u_long), req);
+
+ return (error == 0 ? intr_event_sysctl_intrcnt(oidp, arg1, arg2, req) :
+ error);
}
SYSCTL_PROC(_hw, OID_AUTO, intrcnt,
@@ -743,9 +751,9 @@
#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;
diff --git a/sys/sys/interrupt.h b/sys/sys/interrupt.h
--- a/sys/sys/interrupt.h
+++ b/sys/sys/interrupt.h
@@ -34,6 +34,7 @@
#include <sys/_lock.h>
#include <sys/_mutex.h>
#include <sys/ck.h>
+#include <sys/sysctl.h>
struct intr_event;
struct intr_thread;
@@ -194,4 +195,8 @@
void swi_sched(void *cookie, int flags);
int swi_remove(void *cookie);
+/* For handling the core interrupt counters and names */
+extern int intr_event_sysctl_intrnames(SYSCTL_HANDLER_ARGS);
+extern int intr_event_sysctl_intrcnt(SYSCTL_HANDLER_ARGS);
+
#endif
diff --git a/sys/x86/x86/intr_machdep.c b/sys/x86/x86/intr_machdep.c
--- a/sys/x86/x86/intr_machdep.c
+++ b/sys/x86/x86/intr_machdep.c
@@ -447,8 +447,7 @@
KASSERT(is->is_event != NULL, ("%s: isrc with no event", __func__));
mtx_lock_spin(&intrcnt_lock);
MPASS(intrcnt_index + 2 <= nintrcnt);
- is->is_index = intrcnt_index;
- intrcnt_index += 2;
+ is->is_index = nintrcnt - 2;
snprintf(straystr, sizeof(straystr), "stray irq%d",
is->is_pic->pic_vector(is));
intrcnt_updatename(is);
@@ -738,7 +737,7 @@
isrc->is_index,
isrc->is_cpu,
isrc->is_domain,
- *isrc->is_count);
+ isrc->is_event->ie_intrcnt);
}
sx_sunlock(&intrsrc_lock);
@@ -763,7 +762,7 @@
i1 = *(const struct intsrc * const *)one;
i2 = *(const struct intsrc * const *)two;
if (i1 != NULL && i2 != NULL)
- return (*i1->is_count - *i2->is_count);
+ return (i1->is_event->ie_intrcnt - i2->is_event->ie_intrcnt);
if (i1 != NULL)
return (1);
if (i2 != NULL)
@@ -850,8 +849,14 @@
static int
sysctl_intrnames(SYSCTL_HANDLER_ARGS)
{
- return (sysctl_handle_opaque(oidp, intrnames,
- intrcnt_index * INTRNAME_LEN, req));
+ int error;
+
+ 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,
@@ -862,10 +867,10 @@
static int
sysctl_intrcnt(SYSCTL_HANDLER_ARGS)
{
+ int error;
#ifdef SCTL_MASK32
uint32_t *intrcnt32;
unsigned i;
- int error;
if (req->flags & SCTL_MASK32) {
if (!req->oldptr)
@@ -880,11 +885,13 @@
error = sysctl_handle_opaque(oidp, intrcnt32,
intrcnt_index * sizeof(uint32_t), req);
free(intrcnt32, M_TEMP);
- return (error);
- }
+ } else
#endif
- return (sysctl_handle_opaque(oidp, intrcnt,
- intrcnt_index * sizeof(u_long), req));
+ error = sysctl_handle_opaque(oidp, intrcnt,
+ intrcnt_index * sizeof(u_long), req);
+
+ return (error == 0 ? intr_event_sysctl_intrcnt(oidp, arg1, arg2, req) :
+ error);
}
SYSCTL_PROC(_hw, OID_AUTO, intrcnt,
@@ -894,9 +901,9 @@
#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;

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 13, 4:12 PM (21 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23683048
Default Alt Text
D36610.id116816.diff (9 KB)

Event Timeline