Page MenuHomeFreeBSD

D36610.diff
No OneTemporary

D36610.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
@@ -54,6 +54,7 @@
#include <sys/random.h>
#include <sys/resourcevar.h>
#include <sys/sched.h>
+#include <sys/sbuf.h>
#include <sys/smp.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
@@ -1653,3 +1654,126 @@
}
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 sbuf sbuf;
+ struct intr_event *ie;
+ int error = 0;
+
+ sbuf_new_for_sysctl(&sbuf, NULL, 4096, req);
+ sx_slock(&event_lock);
+ TAILQ_FOREACH(ie, &event_list, ie_list) {
+ if (ie->ie_flags & IE_MULTIPROC) {
+ u_int proc;
+
+ for (proc = 0; proc < mp_ncpus; ++proc) {
+ error = sbuf_printf(&sbuf, "cpu%u:%s%c", proc,
+ ie->ie_fullname, 0);
+ if (error != 0)
+ goto out;
+ }
+ } else {
+ error = sbuf_printf(&sbuf, "%s%c", ie->ie_fullname, 0);
+ if (error != 0)
+ goto out;
+ }
+
+ error = sbuf_printf(&sbuf, "stray %s%c", ie->ie_fullname, 0);
+ if (error != 0)
+ goto out;
+ }
+out:
+ sx_sunlock(&event_lock);
+ error = sbuf_finish(&sbuf);
+ sbuf_delete(&sbuf);
+ return (error);
+}
+
+int
+intr_event_sysctl_intrcnt(SYSCTL_HANDLER_ARGS)
+{
+ struct sbuf sbuf;
+ 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
+
+ sbuf_new_for_sysctl(&sbuf, NULL, 4096, req);
+ sx_slock(&event_lock);
+ TAILQ_FOREACH(ie, &event_list, ie_list) {
+ if (ie->ie_flags & IE_MULTIPROC) {
+ u_int proc;
+
+ for (proc = 0; proc < mp_ncpus; ++proc) {
+#ifdef SCTL_MASK32
+ val32 =
+#endif
+ val = ie->ie_intrcnt[proc];
+ error = sbuf_bcat(&sbuf, arg, sz);
+ if (error != 0)
+ goto out;
+ }
+ } else {
+#ifdef SCTL_MASK32
+ val32 =
+#endif
+ val = ie->ie_intrcnt[0];
+ error = sbuf_bcat(&sbuf, arg, sz);
+ if (error != 0)
+ goto out;
+ }
+
+#ifdef SCTL_MASK32
+ val32 =
+#endif
+ val = ie->ie_stray;
+ error = sbuf_bcat(&sbuf, arg, sz);
+ if (error != 0)
+ goto out;
+ }
+out:
+ sx_sunlock(&event_lock);
+ error = sbuf_finish(&sbuf);
+ sbuf_delete(&sbuf);
+ 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_flags & IE_MULTIPROC) {
+ u_int proc;
+
+ for (proc = 0; proc < mp_ncpus && !db_pager_quit; ++proc)
+ db_printf("cpu%u:%s\t%lu\n", proc,
+ ie->ie_fullname, ie->ie_intrcnt[proc]);
+ if (!db_pager_quit)
+ db_printf("stray %s\t%lu\n", ie->ie_fullname,
+ ie->ie_stray);
+ } else if (ie->ie_intrcnt[0] != 0)
+ db_printf("%s\t%lu\nstray %s\t%lu\n", ie->ie_fullname,
+ ie->ie_intrcnt[0], 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
@@ -273,15 +273,7 @@
mtx_assert(&isrc_table_lock, MA_OWNED);
- /*
- * Allocate two counter values, the second tracking "stray" interrupts.
- */
- bit_ffc_area(intrcnt_bitmap, nintrcnt, 2, &index);
- if (index == -1)
- panic("Failed to allocate 2 counters. Array exhausted?");
- bit_nset(intrcnt_bitmap, index, index + 1);
- if (index >= intrcnt_index)
- intrcnt_index = index + 2;
+ index = nintrcnt - 2;
isrc->isrc_index = index;
isrc->isrc_count = &intrcnt[index];
isrc_update_name(isrc, NULL);
@@ -1593,7 +1585,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] : 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);
@@ -1784,8 +1776,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,
@@ -1796,10 +1794,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)
@@ -1814,11 +1812,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,
@@ -1828,9 +1828,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;
@@ -195,4 +196,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[0]);
}
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[0] - i2->is_event->ie_intrcnt[0]);
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
Fri, Dec 27, 9:55 PM (7 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15617976
Default Alt Text
D36610.diff (10 KB)

Event Timeline