From cabb18f35e3d90d1c197cd119afff47008c62df3 Mon Sep 17 00:00:00 2001 From: grehan Date: Wed, 11 Feb 2004 13:18:31 +0000 Subject: Interrupt statistics, vmstat -i now works. Submitted by: Suleiman Souhlal Slightly modified by: grehan Derived from: i386 --- sys/powerpc/aim/locore.S | 10 ++----- sys/powerpc/include/intr_machdep.h | 3 ++ sys/powerpc/powerpc/genassym.c | 2 ++ sys/powerpc/powerpc/intr_machdep.c | 60 ++++++++++++++++++++++++++++++-------- sys/powerpc/powerpc/locore.S | 10 ++----- 5 files changed, 59 insertions(+), 26 deletions(-) (limited to 'sys/powerpc') diff --git a/sys/powerpc/aim/locore.S b/sys/powerpc/aim/locore.S index 2300d19..9d223bb 100644 --- a/sys/powerpc/aim/locore.S +++ b/sys/powerpc/aim/locore.S @@ -89,17 +89,13 @@ GLOBAL(powersave) .long 0 #define INTSTK 8192 /* 8K interrupt stack */ - -/* - * Dummy interrupt table to keep sysctl happy until - * it's worked out what to do with naming - */ +#define INTRCNT_COUNT 256 /* max(HROWPIC_IRQMAX,OPENPIC_IRQMAX) */ GLOBAL(intrnames) - .asciz "dummy" + .space INTRCNT_COUNT * (MAXCOMLEN + 1) * 2 GLOBAL(eintrnames) .align 4 GLOBAL(intrcnt) - .long 0 + .space INTRCNT_COUNT * 4 * 2 GLOBAL(eintrcnt) /* diff --git a/sys/powerpc/include/intr_machdep.h b/sys/powerpc/include/intr_machdep.h index d2d548e..38de274 100644 --- a/sys/powerpc/include/intr_machdep.h +++ b/sys/powerpc/include/intr_machdep.h @@ -38,6 +38,9 @@ struct intr_handler { struct ithd *ih_ithd; u_int ih_irq; u_int ih_flags; + u_int ih_index; + u_long *ih_count; + u_long *ih_straycount; }; void intr_init(void (*)(void), int, void (*)(uintptr_t), void (*)(uintptr_t)); diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c index eeef0e7..d78d4d6 100644 --- a/sys/powerpc/powerpc/genassym.c +++ b/sys/powerpc/powerpc/genassym.c @@ -192,3 +192,5 @@ ASSYM(TDF_ASTPENDING, TDF_ASTPENDING); ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED); ASSYM(SF_UC, offsetof(struct sigframe, sf_uc)); + +ASSYM(MAXCOMLEN, MAXCOMLEN); diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c index 4f0684d..0af9260 100644 --- a/sys/powerpc/powerpc/intr_machdep.c +++ b/sys/powerpc/powerpc/intr_machdep.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include @@ -89,19 +90,52 @@ static int intr_initialized = 0; static u_int intr_nirq; static struct intr_handler *intr_handlers; -static u_long *intr_stray_count; static struct mtx intr_table_lock; extern int extint, extsize; extern u_long extint_call; +static int intrcnt_index; static ih_func_t intr_stray_handler; static ih_func_t sched_ithd; static void (*irq_enable)(uintptr_t); static void (*irq_disable)(uintptr_t); +static void intrcnt_setname(const char *name, int index); +static void intrcnt_updatename(struct intr_handler *ih); + +static void +intrcnt_setname(const char *name, int index) +{ + snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s", + MAXCOMLEN, name); +} + +static void +intrcnt_updatename(struct intr_handler *ih) +{ + intrcnt_setname(ih->ih_ithd->it_td->td_proc->p_comm, ih->ih_index); +} + +static void +intrcnt_register(struct intr_handler *ih) +{ + char straystr[MAXCOMLEN + 1]; + + KASSERT(ih->ih_ithd != NULL, + ("%s: intr_handler with no ithread", __func__)); + + ih->ih_index = intrcnt_index; + intrcnt_index += 2; + snprintf(straystr, MAXCOMLEN + 1, "stray irq%d", ih->ih_irq); + intrcnt_updatename(ih); + ih->ih_count = &intrcnt[ih->ih_index]; + intrcnt_setname(straystr, ih->ih_index + 1); + ih->ih_straycount = &intrcnt[ih->ih_index + 1]; +} + void intr_init(void (*handler)(void), int nirq, void (*irq_e)(uintptr_t), void (*irq_d)(uintptr_t)) @@ -119,18 +153,19 @@ intr_init(void (*handler)(void), int nirq, void (*irq_e)(uintptr_t), M_NOWAIT|M_ZERO); if (intr_handlers == NULL) panic("intr_init: unable to allocate interrupt handler array"); - intr_stray_count = malloc(nirq * sizeof(u_long), M_INTR, - M_NOWAIT|M_ZERO); - if (intr_stray_count == NULL) - panic("intr_init: unable to allocate interrupt stray array"); for (i = 0; i < nirq; i++) { intr_handlers[i].ih_func = intr_stray_handler; intr_handlers[i].ih_arg = &intr_handlers[i]; intr_handlers[i].ih_irq = i; intr_handlers[i].ih_flags = 0; + /* mux all initial stray irqs onto same count... */ + intr_handlers[i].ih_straycount = &intrcnt[0]; } + intrcnt_setname("???", 0); + intrcnt_index = 1; + msr = mfmsr(); mtmsr(msr & ~PSL_EE); @@ -211,7 +246,7 @@ inthand_add(const char *name, u_int irq, void (*handler)(void *), void *arg, if (flags & INTR_FAST) intr_setup(irq, handler, arg, flags); - intr_stray_count[irq] = 0; + intrcnt_register(ih); return (0); } @@ -244,8 +279,10 @@ inthand_remove(u_int irq, void *cookie) void intr_handle(u_int irq) { - + atomic_add_long(intr_handlers[irq].ih_count, 1); intr_handlers[irq].ih_func(intr_handlers[irq].ih_arg); + + /* XXX wrong thing when using pre-emption ? */ if ((intr_handlers[irq].ih_flags & INTR_FAST) != 0) irq_enable(irq); } @@ -257,14 +294,13 @@ intr_stray_handler(void *cookie) ih = (struct intr_handler *)cookie; - if (intr_stray_count[ih->ih_irq] < MAX_STRAY_LOG) { + if (*intr_handlers[ih->ih_irq].ih_straycount < MAX_STRAY_LOG) { printf("stray irq %d\n", ih->ih_irq); - atomic_add_long(&intr_stray_count[ih->ih_irq], 1); - - if (intr_stray_count[ih->ih_irq] >= MAX_STRAY_LOG) + atomic_add_long(intr_handlers[ih->ih_irq].ih_straycount, 1); + if (*intr_handlers[ih->ih_irq].ih_straycount >= MAX_STRAY_LOG) printf("got %d stray irq %d's: not logging anymore\n", - MAX_STRAY_LOG, ih->ih_irq); + MAX_STRAY_LOG, ih->ih_irq); } } diff --git a/sys/powerpc/powerpc/locore.S b/sys/powerpc/powerpc/locore.S index 2300d19..9d223bb 100644 --- a/sys/powerpc/powerpc/locore.S +++ b/sys/powerpc/powerpc/locore.S @@ -89,17 +89,13 @@ GLOBAL(powersave) .long 0 #define INTSTK 8192 /* 8K interrupt stack */ - -/* - * Dummy interrupt table to keep sysctl happy until - * it's worked out what to do with naming - */ +#define INTRCNT_COUNT 256 /* max(HROWPIC_IRQMAX,OPENPIC_IRQMAX) */ GLOBAL(intrnames) - .asciz "dummy" + .space INTRCNT_COUNT * (MAXCOMLEN + 1) * 2 GLOBAL(eintrnames) .align 4 GLOBAL(intrcnt) - .long 0 + .space INTRCNT_COUNT * 4 * 2 GLOBAL(eintrcnt) /* -- cgit v1.1