summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2003-10-24 21:05:30 +0000
committerjhb <jhb@FreeBSD.org>2003-10-24 21:05:30 +0000
commit7d3a70bca2bcedfcad496a2ef944e323471774b8 (patch)
treee2398f1b33b5045a21ff54e545258b8ec5a59524 /sys
parentc22f9db53f104c1326bf4a9e159fe30e2fa45b93 (diff)
downloadFreeBSD-src-7d3a70bca2bcedfcad496a2ef944e323471774b8.zip
FreeBSD-src-7d3a70bca2bcedfcad496a2ef944e323471774b8.tar.gz
- Add a DDB command 'show intrcnt' to show the non-zero interrupt counts.
- Add a DDB function to dump the contents of an ithread and optionally details about each handler in that ithread. This function can be used by MD code to implement DDB commands that display information about interrupt sources and their registered handlers.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_intr.c165
-rw-r--r--sys/sys/interrupt.h3
2 files changed, 168 insertions, 0 deletions
diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c
index b605edf..a0c2bdc 100644
--- a/sys/kern/kern_intr.c
+++ b/sys/kern/kern_intr.c
@@ -27,6 +27,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_ddb.h"
+
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/conf.h>
@@ -49,6 +51,10 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/md_var.h>
#include <machine/stdarg.h>
+#ifdef DDB
+#include <ddb/ddb.h>
+#include <ddb/db_sym.h>
+#endif
struct int_entropy {
struct proc *proc;
@@ -561,6 +567,143 @@ restart:
}
}
+#ifdef DDB
+/*
+ * Dump details about an interrupt handler
+ */
+static void
+db_dump_intrhand(struct intrhand *ih)
+{
+ int comma;
+
+ db_printf("\t%-10s ", ih->ih_name);
+ switch (ih->ih_pri) {
+ case PI_REALTIME:
+ db_printf("CLK ");
+ break;
+ case PI_AV:
+ db_printf("AV ");
+ break;
+ case PI_TTYHIGH:
+ case PI_TTYLOW:
+ db_printf("TTY ");
+ break;
+ case PI_TAPE:
+ db_printf("TAPE");
+ break;
+ case PI_NET:
+ db_printf("NET ");
+ break;
+ case PI_DISK:
+ case PI_DISKLOW:
+ db_printf("DISK");
+ break;
+ case PI_DULL:
+ db_printf("DULL");
+ break;
+ default:
+ if (ih->ih_pri >= PI_SOFT)
+ db_printf("SWI ");
+ else
+ db_printf("%4u", ih->ih_pri);
+ break;
+ }
+ db_printf(" ");
+ db_printsym((uintptr_t)ih->ih_handler, DB_STGY_PROC);
+ db_printf("(%p)", ih->ih_argument);
+ if (ih->ih_need ||
+ (ih->ih_flags & (IH_FAST | IH_EXCLUSIVE | IH_ENTROPY | IH_DEAD |
+ IH_MPSAFE)) != 0) {
+ db_printf(" {");
+ comma = 0;
+ if (ih->ih_flags & IH_FAST) {
+ db_printf("FAST");
+ comma = 1;
+ }
+ if (ih->ih_flags & IH_EXCLUSIVE) {
+ if (comma)
+ db_printf(", ");
+ db_printf("EXCL");
+ comma = 1;
+ }
+ if (ih->ih_flags & IH_ENTROPY) {
+ if (comma)
+ db_printf(", ");
+ db_printf("ENTROPY");
+ comma = 1;
+ }
+ if (ih->ih_flags & IH_DEAD) {
+ if (comma)
+ db_printf(", ");
+ db_printf("DEAD");
+ comma = 1;
+ }
+ if (ih->ih_flags & IH_MPSAFE) {
+ if (comma)
+ db_printf(", ");
+ db_printf("MPSAFE");
+ comma = 1;
+ }
+ if (ih->ih_need) {
+ if (comma)
+ db_printf(", ");
+ db_printf("NEED");
+ }
+ db_printf("}");
+ }
+ db_printf("\n");
+}
+
+/*
+ * Dump details about an ithread
+ */
+void
+db_dump_ithread(struct ithd *ithd, int handlers)
+{
+ struct proc *p;
+ struct intrhand *ih;
+ int comma;
+
+ if (ithd->it_td != NULL) {
+ p = ithd->it_td->td_proc;
+ db_printf("%s (pid %d)", p->p_comm, p->p_pid);
+ } else
+ db_printf("%s: (no thread)", ithd->it_name);
+ if ((ithd->it_flags & (IT_SOFT | IT_ENTROPY | IT_DEAD)) != 0 ||
+ ithd->it_need) {
+ db_printf(" {");
+ comma = 0;
+ if (ithd->it_flags & IT_SOFT) {
+ db_printf("SOFT");
+ comma = 1;
+ }
+ if (ithd->it_flags & IT_ENTROPY) {
+ if (comma)
+ db_printf(", ");
+ db_printf("ENTROPY");
+ comma = 1;
+ }
+ if (ithd->it_flags & IT_DEAD) {
+ if (comma)
+ db_printf(", ");
+ db_printf("DEAD");
+ comma = 1;
+ }
+ if (ithd->it_need) {
+ if (comma)
+ db_printf(", ");
+ db_printf("NEED");
+ }
+ db_printf("}");
+ }
+ db_printf("\n");
+
+ if (handlers)
+ TAILQ_FOREACH(ih, &ithd->it_handlers, ih_next)
+ db_dump_intrhand(ih);
+}
+#endif /* DDB */
+
/*
* Start standard software interrupt threads
*/
@@ -609,3 +752,25 @@ sysctl_intrcnt(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_hw, OID_AUTO, intrcnt, CTLTYPE_OPAQUE | CTLFLAG_RD,
NULL, 0, sysctl_intrcnt, "", "Interrupt Counts");
+
+#ifdef DDB
+/*
+ * DDB command to dump the interrupt statistics.
+ */
+DB_SHOW_COMMAND(intrcnt, db_show_intrcnt)
+{
+ u_long *i;
+ char *cp;
+ int quit;
+
+ cp = intrnames;
+ db_setup_paging(db_simple_pager, &quit, DB_LINES_PER_PAGE);
+ for (i = intrcnt, quit = 0; i != eintrcnt && !quit; i++) {
+ if (*cp == '\0')
+ break;
+ if (*i != 0)
+ db_printf("%s\t%lu\n", cp, *i);
+ cp += strlen(cp) + 1;
+ }
+}
+#endif
diff --git a/sys/sys/interrupt.h b/sys/sys/interrupt.h
index 58a9dd0..cdf829d 100644
--- a/sys/sys/interrupt.h
+++ b/sys/sys/interrupt.h
@@ -111,6 +111,9 @@ extern char eintrnames[]; /* end of intrnames[] */
extern u_long intrcnt[]; /* counts for for each device and stray */
extern char intrnames[]; /* string table containing device names */
+#ifdef DDB
+void db_dump_ithread(struct ithd *ithd, int handlers);
+#endif
int ithread_create(struct ithd **ithread, int vector, int flags,
void (*disable)(int), void (*enable)(int), const char *fmt, ...)
__printflike(6, 7);
OpenPOWER on IntegriCloud