diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -749,7 +749,7 @@ xhits_gbl[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invltlb_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invltlb_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ if (smp_tlb_pmap == kernel_pmap) @@ -767,7 +767,7 @@ xhits_gbl[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invltlb_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invltlb_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ d.pcid = smp_tlb_pmap->pm_pcids[PCPU_GET(cpuid)].pm_pcid; @@ -786,7 +786,7 @@ xhits_gbl[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invltlb_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invltlb_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ d.pcid = smp_tlb_pmap->pm_pcids[PCPU_GET(cpuid)].pm_pcid; @@ -817,7 +817,7 @@ xhits_gbl[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invltlb_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invltlb_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ if (smp_tlb_pmap == kernel_pmap) { @@ -846,7 +846,7 @@ xhits_pg[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invlpg_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invlpg_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ invlpg(smp_tlb_addr1); @@ -861,7 +861,7 @@ xhits_pg[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invlpg_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invlpg_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ invlpg(smp_tlb_addr1); @@ -886,7 +886,7 @@ xhits_pg[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invlpg_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invlpg_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ invlpg(smp_tlb_addr1); @@ -909,7 +909,7 @@ xhits_rng[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invlrng_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invlrng_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ addr = smp_tlb_addr1; @@ -931,7 +931,7 @@ xhits_rng[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invlrng_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invlrng_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ addr = smp_tlb_addr1; @@ -966,7 +966,7 @@ xhits_rng[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invlrng_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invlrng_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ addr = smp_tlb_addr1; @@ -989,7 +989,7 @@ invlcache_handler(void) { #ifdef COUNT_IPIS - (*ipi_invlcache_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invlcache_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ wbinvd(); } diff --git a/sys/arm/arm/machdep_intr.c b/sys/arm/arm/machdep_intr.c --- a/sys/arm/arm/machdep_intr.c +++ b/sys/arm/arm/machdep_intr.c @@ -60,7 +60,7 @@ intr_ipi_send_t * ii_send; void * ii_send_arg; char ii_name[INTR_IPI_NAMELEN]; - u_long * ii_count; + struct intr_event * ii_count[MAXCPU]; }; static struct intr_ipi ipi_sources[INTR_IPI_COUNT]; @@ -147,10 +147,10 @@ struct intr_ipi *ii; ii = intr_ipi_lookup(ipi); - if (ii->ii_count == NULL) + if (ii->ii_count[nitems(ii->ii_count) - 1] == NULL) panic("%s: not setup IPI %u", __func__, ipi); - intr_ipi_increment_count(ii->ii_count, PCPU_GET(cpuid)); + atomic_add_long(&ii->ii_count[PCPU_GET(cpuid)]->ie_intrcnt, 1); /* * Supply ipi filter with trapframe argument @@ -166,7 +166,7 @@ struct intr_ipi *ii; ii = intr_ipi_lookup(ipi); - if (ii->ii_count == NULL) + if (ii->ii_count[nitems(ii->ii_count) - 1] == NULL) panic("%s: not setup IPI %u", __func__, ipi); ii->ii_send(ii->ii_send_arg, cpus, ipi); @@ -177,19 +177,28 @@ void *h_arg, intr_ipi_send_t *send, void *s_arg) { struct intr_ipi *ii; + int error; + u_int i; ii = intr_ipi_lookup(ipi); KASSERT(hand != NULL, ("%s: ipi %u no handler", __func__, ipi)); KASSERT(send != NULL, ("%s: ipi %u no sender", __func__, ipi)); - KASSERT(ii->ii_count == NULL, ("%s: ipi %u reused", __func__, ipi)); + KASSERT(ii->ii_count[0] == NULL, ("%s: ipi %u reused", __func__, ipi)); ii->ii_handler = hand; ii->ii_handler_arg = h_arg; ii->ii_send = send; ii->ii_send_arg = s_arg; strlcpy(ii->ii_name, name, INTR_IPI_NAMELEN); - ii->ii_count = intr_ipi_setup_counters(name); + + for (i = 0; i < MAXCPU; ++i) { + error = intr_event_create(ii->ii_count + i, NULL, 0, NULL, + NULL, NULL, NULL, "cpu%d:%s", i, name); + if (error != 0) + panic("%s(): intr_event_create() failed, return=%d", + __func__, error); + } } /* diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -111,7 +112,7 @@ intr_ipi_send_t * ii_send; void * ii_send_arg; char ii_name[INTR_IPI_NAMELEN]; - u_long * ii_count; + struct intr_event * ii_count[MAXCPU]; }; static struct intr_ipi ipi_sources[INTR_IPI_COUNT]; @@ -355,6 +356,7 @@ struct intr_irqsrc *isrc; struct intr_ipi *ii; int error; + u_int i; KASSERT(intr_irq_root_dev != NULL, ("%s: no root attached", __func__)); KASSERT(hand != NULL, ("%s: ipi %u no handler", __func__, ipi)); @@ -366,14 +368,21 @@ isrc->isrc_handlers++; ii = intr_ipi_lookup(ipi); - KASSERT(ii->ii_count == NULL, ("%s: ipi %u reused", __func__, ipi)); + KASSERT(ii->ii_count[0] == NULL, ("%s: ipi %u reused", __func__, ipi)); ii->ii_handler = hand; ii->ii_handler_arg = arg; ii->ii_send = pic_ipi_send; ii->ii_send_arg = isrc; strlcpy(ii->ii_name, name, INTR_IPI_NAMELEN); - ii->ii_count = intr_ipi_setup_counters(name); + + for (i = 0; i < MAXCPU; ++i) { + error = intr_event_create(ii->ii_count + i, NULL, 0, NULL, + NULL, NULL, NULL, "cpu%d:%s", i, name); + if (error != 0) + panic("%s(): intr_event_create() failed, return=%d", + __func__, error); + } PIC_ENABLE_INTR(intr_irq_root_dev, isrc); } @@ -384,7 +393,7 @@ struct intr_ipi *ii; ii = intr_ipi_lookup(ipi); - if (ii->ii_count == NULL) + if (ii->ii_count[nitems(ii->ii_count) - 1] == NULL) panic("%s: not setup IPI %u", __func__, ipi); ii->ii_send(ii->ii_send_arg, cpus, ipi); @@ -838,10 +847,10 @@ struct intr_ipi *ii; ii = intr_ipi_lookup(ipi); - if (ii->ii_count == NULL) + if (ii->ii_count[nitems(ii->ii_count) - 1] == NULL) panic("%s: not setup IPI %u", __func__, ipi); - intr_ipi_increment_count(ii->ii_count, PCPU_GET(cpuid)); + atomic_add_long(&ii->ii_count[PCPU_GET(cpuid)]->ie_intrcnt, 1); /* * Supply ipi filter with trapframe argument diff --git a/sys/dev/hyperv/vmbus/vmbus.c b/sys/dev/hyperv/vmbus/vmbus.c --- a/sys/dev/hyperv/vmbus/vmbus.c +++ b/sys/dev/hyperv/vmbus/vmbus.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -744,7 +745,7 @@ /* * Do a little interrupt counting. */ - (*VMBUS_PCPU_GET(sc, intr_cnt, cpu))++; + VMBUS_PCPU_GET(sc, intr_cnt, cpu)->ie_intrcnt++; vmbus_handle_intr1(sc, trap_frame, cpu); @@ -947,12 +948,14 @@ int cpu; CPU_FOREACH(cpu) { - char buf[MAXCOMLEN + 1]; cpuset_t cpu_mask; + int error; /* Allocate an interrupt counter for Hyper-V interrupt */ - snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu); - intrcnt_add(buf, VMBUS_PCPU_PTR(sc, intr_cnt, cpu)); + error = intr_event_create(VMBUS_PCPU_PTR(sc, intr_cnt, cpu), + NULL, 0, NULL, NULL, NULL, NULL, "cpu%d:hyperv", cpu); + if (error != 0) + return (error); /* * Setup taskqueue to handle events. Task will be per- @@ -1025,6 +1028,10 @@ #endif CPU_FOREACH(cpu) { + if (VMBUS_PCPU_GET(sc, intr_cnt, cpu) != NULL) { + intr_event_destroy(VMBUS_PCPU_GET(sc, intr_cnt, cpu)); + VMBUS_PCPU_GET(sc, intr_cnt, cpu) = NULL; + } if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) { taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu)); VMBUS_PCPU_GET(sc, event_tq, cpu) = NULL; diff --git a/sys/dev/hyperv/vmbus/vmbus_var.h b/sys/dev/hyperv/vmbus/vmbus_var.h --- a/sys/dev/hyperv/vmbus/vmbus_var.h +++ b/sys/dev/hyperv/vmbus/vmbus_var.h @@ -67,7 +67,7 @@ VMBUS_CHANMSG_PROC(name, vmbus_msghc_wakeup) struct vmbus_pcpu_data { - u_long *intr_cnt; /* Hyper-V interrupt counter */ + struct intr_event *intr_cnt; /* Hyper-V interrupt counter */ struct vmbus_message *message; /* shared messages */ uint32_t vcpuid; /* virtual cpuid */ int event_flags_cnt;/* # of event flags */ diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -663,7 +663,7 @@ xhits_gbl[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invltlb_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invltlb_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ /* @@ -686,7 +686,7 @@ xhits_pg[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invlpg_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invlpg_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ generation = smp_tlb_generation; /* Overlap with serialization */ @@ -706,7 +706,7 @@ xhits_rng[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invlrng_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invlrng_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ addr = smp_tlb_addr1; @@ -729,7 +729,7 @@ trap_check_kstack(); #ifdef COUNT_IPIS - (*ipi_invlcache_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_invlcache_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ /* diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -74,6 +74,8 @@ #include #include +#include + #ifdef GPROF #include #endif @@ -835,22 +837,15 @@ static void watchdog_fire(void) { - int nintr; - uint64_t inttotal; - u_long *curintr; - char *curname; - - curintr = intrcnt; - curname = intrnames; - inttotal = 0; - nintr = sintrcnt / sizeof(u_long); + uint64_t inttotal = 0; + u_int curintr; + const struct intr_event *ie; printf("interrupt total\n"); - while (--nintr >= 0) { - if (*curintr) - printf("%-12s %20lu\n", curname, *curintr); - curname += strlen(curname) + 1; - inttotal += *curintr++; + INTR_FOREACH(curintr) { + ie = intr2event(intr_lookup(curintr)); + printf("%-12s %20lu\n", ie->ie_fullname, ie->ie_intrcnt); + inttotal += ie->ie_intrcnt; } printf("Total %20ju\n", (uintmax_t)inttotal); 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 #include #include +#include #include #include #include @@ -110,8 +111,8 @@ #endif static TAILQ_HEAD(, intr_event) event_list = TAILQ_HEAD_INITIALIZER(event_list); -static struct mtx event_lock; -MTX_SYSINIT(intr_event_list, &event_lock, "intr event list", MTX_DEF); +static struct sx event_lock; +SX_SYSINIT(intr_event_list, &event_lock, "intr event list"); static void intr_event_update(struct intr_event *ie); static int intr_event_schedule_thread(struct intr_event *ie, struct trapframe *frame); @@ -338,14 +339,16 @@ ie->ie_assign_cpu = assign_cpu; ie->ie_flags = flags; ie->ie_cpu = NOCPU; + ie->ie_stray = 0; + ie->ie_intrcnt = 0; CK_SLIST_INIT(&ie->ie_handlers); mtx_init(&ie->ie_lock, "intr event", NULL, MTX_DEF); vsnprintf(ie->ie_name, sizeof(ie->ie_name), fmt, ap); strlcpy(ie->ie_fullname, ie->ie_name, sizeof(ie->ie_fullname)); - mtx_lock(&event_lock); + sx_xlock(&event_lock); TAILQ_INSERT_TAIL(&event_list, ie, ie_list); - mtx_unlock(&event_lock); + sx_xunlock(&event_lock); CTR2(KTR_INTR, "%s: created %s", __func__, ie->ie_name); return (0); } @@ -558,11 +561,11 @@ intr_event_shutdown(struct intr_event *ie) { - mtx_lock(&event_lock); + sx_xlock(&event_lock); mtx_lock(&ie->ie_lock); if (!CK_SLIST_EMPTY(&ie->ie_handlers)) { mtx_unlock(&ie->ie_lock); - mtx_unlock(&event_lock); + sx_xunlock(&event_lock); return (EBUSY); } TAILQ_REMOVE(&event_list, ie, ie_list); @@ -573,7 +576,7 @@ } #endif mtx_unlock(&ie->ie_lock); - mtx_unlock(&event_lock); + sx_xunlock(&event_lock); mtx_destroy(&ie->ie_lock); return (0); } @@ -1386,13 +1389,18 @@ td = curthread; + /* Increment the interrupt counter. */ + atomic_add_long(&ie->ie_intrcnt, 1); + #ifdef KSTACK_USAGE_PROF intr_prof_stack_use(td, frame); #endif /* An interrupt with no event or handlers is a stray interrupt. */ - if (ie == NULL || CK_SLIST_EMPTY(&ie->ie_handlers)) + if (ie == NULL || CK_SLIST_EMPTY(&ie->ie_handlers)) { + atomic_add_long(&ie->ie_stray, 1); return (EINVAL); + } /* * Execute fast interrupt handlers directly. @@ -1489,8 +1497,10 @@ td->td_intr_nesting_level--; #ifdef notyet /* The interrupt is not aknowledged by any filter and has no ithread. */ - if (!thread && !filter) + if (!thread && !filter) { + atomic_add_long(&ie->ie_stray, 1); return (EINVAL); + } #endif return (0); } @@ -1650,17 +1660,41 @@ /* * Sysctls used by systat and others: hw.intrnames and hw.intrcnt. - * The data for this machine dependent, and the declarations are in machine - * dependent code. The layout of intrnames and intrcnt however is machine - * independent. - * - * We do not know the length of intrcnt and intrnames at compile time, so - * calculate things at run time. + * The data for this machine independent. */ static int sysctl_intrnames(SYSCTL_HANDLER_ARGS) { - return (sysctl_handle_opaque(oidp, intrnames, sintrnames, req)); + struct intr_event *ie; + const char straystr[] = "stray ", padstr[sizeof(straystr)] = ""; + int error; + + sx_slock(&event_lock); + TAILQ_FOREACH(ie, &event_list, ie_list) { + error = SYSCTL_OUT(req, ie->ie_fullname, + sizeof(ie->ie_fullname)); + if (error != 0) + return (error); + error = SYSCTL_OUT(req, padstr, sizeof(padstr) - 1); + if (error != 0) + return (error); + error = SYSCTL_OUT(req, "", 1); + if (error != 0) + return (error); + + error = SYSCTL_OUT(req, straystr, sizeof(straystr) - 1); + if (error != 0) + return (error); + error = SYSCTL_OUT(req, ie->ie_fullname, + sizeof(ie->ie_fullname)); + if (error != 0) + return (error); + error = SYSCTL_OUT(req, "", 1); + if (error != 0) + return (error); + } + sx_sunlock(&event_lock); + return (0); } SYSCTL_PROC(_hw, OID_AUTO, intrnames, @@ -1671,25 +1705,40 @@ static int sysctl_intrcnt(SYSCTL_HANDLER_ARGS) { -#ifdef SCTL_MASK32 - uint32_t *intrcnt32; - unsigned i; + struct intr_event *ie; int error; + int sz = sizeof(ie->ie_intrcnt); + u_long val; + void *arg = &val; +#ifdef SCTL_MASK32 + uint32_t val32; if (req->flags & SCTL_MASK32) { - if (!req->oldptr) - return (sysctl_handle_opaque(oidp, NULL, sintrcnt / 2, req)); - intrcnt32 = malloc(sintrcnt / 2, M_TEMP, M_NOWAIT); - if (intrcnt32 == NULL) - return (ENOMEM); - for (i = 0; i < sintrcnt / sizeof (u_long); i++) - intrcnt32[i] = intrcnt[i]; - error = sysctl_handle_opaque(oidp, intrcnt32, sintrcnt / 2, req); - free(intrcnt32, M_TEMP); - return (error); + sz = sizeof(val32); + arg = &val32; } #endif - return (sysctl_handle_opaque(oidp, intrcnt, sintrcnt, req)); + + sx_slock(&event_lock); + TAILQ_FOREACH(ie, &event_list, ie_list) { +#ifdef SCTL_MASK32 + val32 = +#endif + val = ie->ie_intrcnt; + error = SYSCTL_OUT(req, arg, sz); + if (error != 0) + return (error); + +#ifdef SCTL_MASK32 + val32 = +#endif + val = ie->ie_stray; + error = SYSCTL_OUT(req, arg, sz); + if (error != 0) + return (error); + } + sx_sunlock(&event_lock); + return (0); } SYSCTL_PROC(_hw, OID_AUTO, intrcnt, @@ -1703,19 +1752,11 @@ */ DB_SHOW_COMMAND_FLAGS(intrcnt, db_show_intrcnt, DB_CMD_MEMSAFE) { - u_long *i; - char *cp; - u_int j; - - cp = intrnames; - j = 0; - for (i = intrcnt; j < (sintrcnt / sizeof(u_long)) && !db_pager_quit; - i++, j++) { - if (*cp == '\0') - break; - if (*i != 0) - db_printf("%s\t%lu\n", cp, *i); - cp += strlen(cp) + 1; - } + struct intr_event *ie; + + for (ie = TAILQ_FIRST(&event_list); ie && !db_pager_quit; + ie = TAILQ_NEXT(ie, ie_list)) + 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 @@ -147,13 +147,6 @@ SYSCTL_UINT(_machdep, OID_AUTO, nirq, CTLFLAG_RDTUN, &intr_nirq, 0, "Number of IRQs"); -/* Data for MI statistics reporting. */ -u_long *intrcnt; -char *intrnames; -size_t sintrcnt; -size_t sintrnames; -static u_int intrcnt_index; - static struct intr_irqsrc *intr_map_get_isrc(u_int res_id); static void intr_map_set_isrc(u_int res_id, struct intr_irqsrc *isrc); static struct intr_map_data * intr_map_get_map_data(u_int res_id); @@ -166,76 +159,18 @@ static void intr_irq_init(void *dummy __unused) { - u_int intrcnt_count; SLIST_INIT(&pic_list); mtx_init(&pic_list_lock, "intr pic list", NULL, MTX_DEF); mtx_init(&isrc_table_lock, "intr isrc table", NULL, MTX_DEF); - /* - * - 2 counters for each I/O interrupt. - * - MAXCPU counters for each IPI counters for SMP. - */ - intrcnt_count = intr_nirq * 2; -#ifdef SMP - intrcnt_count += INTR_IPI_COUNT * MAXCPU; -#endif - - intrcnt = mallocarray(intrcnt_count, sizeof(u_long), M_INTRNG, - M_WAITOK | M_ZERO); - intrnames = mallocarray(intrcnt_count, INTRNAME_LEN, M_INTRNG, - M_WAITOK | M_ZERO); - sintrcnt = intrcnt_count * sizeof(u_long); - sintrnames = intrcnt_count * INTRNAME_LEN; irq_sources = mallocarray(intr_nirq, sizeof(struct intr_irqsrc*), M_INTRNG, M_WAITOK | M_ZERO); } SYSINIT(intr_irq_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_irq_init, NULL); -static void -intrcnt_setname(const char *name, int index) -{ - - snprintf(intrnames + INTRNAME_LEN * index, INTRNAME_LEN, "%-*s", - INTRNAME_LEN - 1, name); -} - -/* - * Update name for interrupt source with interrupt event. - */ -static void -intrcnt_updatename(struct intr_irqsrc *isrc) -{ - - /* QQQ: What about stray counter name? */ - mtx_assert(&isrc_table_lock, MA_OWNED); - intrcnt_setname(isrc->isrc_event->ie_fullname, isrc->isrc_index); -} - -/* - * Virtualization for interrupt source interrupt counter increment. - */ -static inline void -isrc_increment_count(struct intr_irqsrc *isrc) -{ - - if (isrc->isrc_flags & INTR_ISRCF_PPI) - atomic_add_long(&isrc->isrc_count[0], 1); - else - isrc->isrc_count[0]++; -} - -/* - * Virtualization for interrupt source interrupt stray counter increment. - */ -static inline u_long -isrc_increment_straycount(struct intr_irqsrc *isrc) -{ - - return (++isrc->isrc_count[1]); -} - +#ifdef INTR_SOLO /* * Virtualization for interrupt source interrupt name update. */ @@ -246,64 +181,13 @@ mtx_assert(&isrc_table_lock, MA_OWNED); - if (name != NULL) { + if (name != NULL) snprintf(str, INTRNAME_LEN, "%s: %s", isrc->isrc_name, name); - intrcnt_setname(str, isrc->isrc_index); - snprintf(str, INTRNAME_LEN, "stray %s: %s", isrc->isrc_name, - name); - intrcnt_setname(str, isrc->isrc_index + 1); - } else { + else snprintf(str, INTRNAME_LEN, "%s:", isrc->isrc_name); - intrcnt_setname(str, isrc->isrc_index); - snprintf(str, INTRNAME_LEN, "stray %s:", isrc->isrc_name); - intrcnt_setname(str, isrc->isrc_index + 1); - } -} - -/* - * Virtualization for interrupt source interrupt counters setup. - */ -static void -isrc_setup_counters(struct intr_irqsrc *isrc) -{ - u_int index; - - /* - * XXX - it does not work well with removable controllers and - * interrupt sources !!! - */ - index = atomic_fetchadd_int(&intrcnt_index, 2); - isrc->isrc_index = index; - isrc->isrc_count = &intrcnt[index]; - isrc_update_name(isrc, NULL); -} - -/* - * Virtualization for interrupt source interrupt counters release. - */ -static void -isrc_release_counters(struct intr_irqsrc *isrc) -{ - panic("%s: not implemented", __func__); -} - -#ifdef SMP -/* - * Virtualization for interrupt source IPI counters setup. - */ -u_long * -intr_ipi_setup_counters(const char *name) -{ - u_int index, i; - char str[INTRNAME_LEN]; - - index = atomic_fetchadd_int(&intrcnt_index, MAXCPU); - for (i = 0; i < MAXCPU; i++) { - snprintf(str, INTRNAME_LEN, "cpu%d:%s", i, name); - intrcnt_setname(str, index + i); - } - return (&intrcnt[index]); + strlcpy(isrc->isrc_event->ie_fullname, str, + sizeof(isrc->isrc_event->ie_fullname)); } #endif @@ -368,8 +252,6 @@ KASSERT(isrc != NULL, ("%s: no source", __func__)); - isrc_increment_count(isrc); - #ifdef INTR_SOLO if (isrc->isrc_filter != NULL) { int error; @@ -382,9 +264,10 @@ if (isrc->isrc_event != NULL) { if (intr_event_handle(isrc->isrc_event, tf) == 0) return (0); + return (isrc->isrc_event->ie_stray); } - return (isrc_increment_straycount(isrc)); + return (-1); } /* @@ -494,13 +377,7 @@ mtx_unlock(&isrc_table_lock); return (error); } - /* - * Setup interrupt counters, but not for IPI sources. Those are setup - * later and only for used ones (up to INTR_IPI_COUNT) to not exhaust - * our counter pool. - */ - if ((isrc->isrc_flags & INTR_ISRCF_IPI) == 0) - isrc_setup_counters(isrc); + mtx_unlock(&isrc_table_lock); return (0); } @@ -514,8 +391,6 @@ int error; mtx_lock(&isrc_table_lock); - if ((isrc->isrc_flags & INTR_ISRCF_IPI) == 0) - isrc_release_counters(isrc); error = isrc_free_irq(isrc); mtx_unlock(&isrc_table_lock); return (error); @@ -731,15 +606,8 @@ return (error); } - error = intr_event_add_handler(isrc->isrc_event, name, filter, handler, - arg, intr_priority(flags), flags, cookiep); - if (error == 0) { - mtx_lock(&isrc_table_lock); - intrcnt_updatename(isrc); - mtx_unlock(&isrc_table_lock); - } - - return (error); + return (intr_event_add_handler(isrc->isrc_event, name, filter, handler, + arg, intr_priority(flags), flags, cookiep)); } /* @@ -1169,7 +1037,6 @@ if (isrc->isrc_handlers == 0) PIC_DISABLE_INTR(isrc->isrc_dev, isrc); PIC_TEARDOWN_INTR(isrc->isrc_dev, isrc, res, data); - intrcnt_updatename(isrc); mtx_unlock(&isrc_table_lock); } return (error); @@ -1179,7 +1046,6 @@ intr_describe_irq(device_t dev, struct resource *res, void *cookie, const char *descr) { - int error; struct intr_irqsrc *isrc; u_int res_id; @@ -1201,13 +1067,7 @@ return (0); } #endif - error = intr_event_describe_handler(isrc->isrc_event, cookie, descr); - if (error == 0) { - mtx_lock(&isrc_table_lock); - intrcnt_updatename(isrc); - mtx_unlock(&isrc_table_lock); - } - return (error); + return (intr_event_describe_handler(isrc->isrc_event, cookie, descr)); } #ifdef SMP @@ -1579,7 +1439,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); diff --git a/sys/powerpc/include/intr.h b/sys/powerpc/include/intr.h --- a/sys/powerpc/include/intr.h +++ b/sys/powerpc/include/intr.h @@ -61,8 +61,6 @@ driver_filter_t powerpc_ipi_handler; -void intrcnt_add(const char *name, u_long **countp); - u_int powerpc_register_pic(device_t, uint32_t, u_int, u_int, u_int); u_int powerpc_get_irq(uint32_t, u_int); diff --git a/sys/powerpc/powerpc/clock.c b/sys/powerpc/powerpc/clock.c --- a/sys/powerpc/powerpc/clock.c +++ b/sys/powerpc/powerpc/clock.c @@ -86,10 +86,10 @@ /* * Initially we assume a processor with a bus frequency of 12.5 MHz. */ -static int initialized = 0; -static uint64_t ps_per_tick = 80000; -static u_long ticks_per_sec = 12500000; -static u_long *decr_counts[MAXCPU]; +static int initialized = 0; +static uint64_t ps_per_tick = 80000; +static u_long ticks_per_sec = 12500000; +static struct intr_event *decr_counts[MAXCPU]; static int decr_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period); @@ -133,7 +133,7 @@ if (!initialized) return; - (*decr_counts[curcpu])++; + decr_counts[curcpu]->ie_intrcnt++; #ifdef BOOKE /* @@ -183,7 +183,7 @@ decr_init(void) { struct cpuref cpu; - char buf[32]; + int error; /* * Check the BSP's timebase frequency. Sometimes we can't find the BSP, @@ -195,8 +195,13 @@ ps_per_tick = 1000000000000 / ticks_per_sec; set_cputicker(mftb, ticks_per_sec, false); - snprintf(buf, sizeof(buf), "cpu%d:decrementer", curcpu); - intrcnt_add(buf, &decr_counts[curcpu]); + if (decr_counts[curcpu] != NULL) { + error = intr_event_create(decr_counts + curcpu, NULL, 0, NULL, + NULL, NULL, NULL, "cpu%d:decrementer", curcpu); + if (error != 0) + panic("%s(): intr_event_create() failed, return=%d", + __func__, error); + } decr_et_stop(NULL); initialized = 1; } @@ -208,10 +213,15 @@ void decr_ap_init(void) { - char buf[32]; - - snprintf(buf, sizeof(buf), "cpu%d:decrementer", curcpu); - intrcnt_add(buf, &decr_counts[curcpu]); + int error; + + if (decr_counts[curcpu] != NULL) { + error = intr_event_create(decr_counts + curcpu, NULL, 0, NULL, + NULL, NULL, NULL, "cpu%d:decrementer", curcpu); + if (error != 0) + panic("%s(): intr_event_create() failed, return=%d", + __func__, error); + } decr_et_stop(NULL); } #endif 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 @@ -97,13 +97,11 @@ struct powerpc_intr { struct intr_event *event; - long *cntp; void *priv; /* PIC-private data */ device_t pic; u_int irq; u_int intline; u_int vector; - u_int cntindex; int fwcode; int ipi; int pi_domain; @@ -120,7 +118,6 @@ int base; }; -static u_int intrcnt_index = 0; static struct mtx intr_table_lock; static struct powerpc_intr **powerpc_intrs; static struct pic piclist[MAX_PICS]; @@ -133,12 +130,6 @@ #endif static u_int stray_count; -u_long *intrcnt; -char *intrnames; -size_t sintrcnt = sizeof(intrcnt); -size_t sintrnames = sizeof(intrnames); -int nintrcnt; - /* * Just to start */ @@ -154,14 +145,6 @@ static void *ipi_cookie; #endif -static void -intrcnt_setname(const char *name, int index) -{ - - snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s", - MAXCOMLEN, name); -} - static void intr_init(void *dummy __unused) { @@ -176,20 +159,6 @@ powerpc_intrs = mallocarray(num_io_irqs, sizeof(*powerpc_intrs), M_INTR, M_WAITOK | M_ZERO); - nintrcnt = 1 + num_io_irqs * 2 + mp_ncpus * 2; -#ifdef COUNT_IPIS - if (mp_ncpus > 1) - nintrcnt += 8 * mp_ncpus; -#endif - intrcnt = mallocarray(nintrcnt, sizeof(u_long), M_INTR, M_WAITOK | - M_ZERO); - intrnames = mallocarray(nintrcnt, MAXCOMLEN + 1, M_INTR, M_WAITOK | - M_ZERO); - sintrcnt = nintrcnt * sizeof(u_long); - sintrnames = nintrcnt * (MAXCOMLEN + 1); - - intrcnt_setname("???", 0); - intrcnt_index = 1; } /* * This needs to happen before SI_SUB_CPU @@ -212,23 +181,10 @@ SYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL); #endif -void -intrcnt_add(const char *name, u_long **countp) -{ - int idx; - - idx = atomic_fetchadd_int(&intrcnt_index, 1); - KASSERT(idx < nintrcnt, ("intrcnt_add: Interrupt counter index %d/%d" - "reached nintrcnt : %d", intrcnt_index, idx, nintrcnt)); - *countp = &intrcnt[idx]; - intrcnt_setname(name, idx); -} - extern void kdb_backtrace(void); static struct powerpc_intr * intr_create(u_int irq) { - char intrname[16]; struct powerpc_intr *i, *iscan; int vector; @@ -248,7 +204,6 @@ } i->event = NULL; - i->cntp = NULL; i->priv = NULL; i->trig = INTR_TRIGGER_CONFORM; i->pol = INTR_POLARITY_CONFORM; @@ -276,10 +231,8 @@ if (iscan == NULL && i->vector != -1) { powerpc_intrs[i->vector] = i; - i->cntindex = atomic_fetchadd_int(&intrcnt_index, 1); - i->cntp = &intrcnt[i->cntindex]; - sprintf(intrname, "irq%u:", i->irq); - intrcnt_setname(intrname, i->cntindex); + snprintf(i->event->ie_fullname, sizeof(i->event->ie_fullname), + "irq%u:", i->irq); nvectors++; } mtx_unlock(&intr_table_lock); @@ -580,9 +533,6 @@ CPU_ZERO(&i->pi_cpuset); CPU_COPY(&cpuset_domain[domain], &i->pi_cpuset); } - mtx_lock(&intr_table_lock); - intrcnt_setname(i->event->ie_fullname, i->cntindex); - mtx_unlock(&intr_table_lock); if (!cold) { error = powerpc_map_irq(i); @@ -678,8 +628,6 @@ if (i == NULL) goto stray; - (*i->cntp)++; - ie = i->event; KASSERT(ie != NULL, ("%s: interrupt without an event", __func__)); diff --git a/sys/sys/interrupt.h b/sys/sys/interrupt.h --- a/sys/sys/interrupt.h +++ b/sys/sys/interrupt.h @@ -126,6 +126,8 @@ int ie_cpu; /* CPU this event is bound to. */ volatile int ie_phase; /* Switched to establish a barrier. */ volatile int ie_active[2]; /* Filters in ISR context. */ + u_long ie_stray; /* Stray interrupt counter */ + u_long ie_intrcnt; /* Interrupt counter */ }; /* Interrupt event flags kept in ie_flags. */ @@ -158,12 +160,6 @@ extern struct intr_event *tty_intr_event; extern void *vm_ih; -/* Counts and names for statistics (defined in MD code). */ -extern u_long *intrcnt; /* counts for each device and stray */ -extern char *intrnames; /* string table containing device names */ -extern size_t sintrcnt; /* size of intrcnt table */ -extern size_t sintrnames; /* size of intrnames table */ - #ifdef DDB void db_dump_intr_event(struct intr_event *ie, int handlers); #endif diff --git a/sys/sys/intr.h b/sys/sys/intr.h --- a/sys/sys/intr.h +++ b/sys/sys/intr.h @@ -105,8 +105,6 @@ u_int isrc_flags; char isrc_name[INTR_ISRC_NAMELEN]; cpuset_t isrc_cpu; /* on which CPUs is enabled */ - u_int isrc_index; - u_long * isrc_count; u_int isrc_handlers; struct intr_event * isrc_event; #ifdef INTR_SOLO @@ -170,18 +168,6 @@ void intr_pic_init_secondary(void); -/* Virtualization for interrupt source IPI counter increment. */ -static inline void -intr_ipi_increment_count(u_long *counter, u_int cpu) -{ - - KASSERT(cpu < MAXCPU, ("%s: too big cpu %u", __func__, cpu)); - counter[cpu]++; -} - -/* Virtualization for interrupt source IPI counters setup. */ -u_long * intr_ipi_setup_counters(const char *name); - #endif extern u_int intr_nirq; /* number of IRQs on intrng platforms */ diff --git a/sys/x86/include/intr.h b/sys/x86/include/intr.h --- a/sys/x86/include/intr.h +++ b/sys/x86/include/intr.h @@ -127,9 +127,6 @@ struct intsrc { struct pic *is_pic; struct intr_event *is_event; - u_long *is_count; - u_long *is_straycount; - u_int is_index; u_int is_handlers; u_int is_domain; u_int is_cpu; @@ -175,7 +172,6 @@ void intr_resume(bool suspend_cancelled); void intr_suspend(void); void intr_reprogram(void); -void intrcnt_add(const char *name, u_long **countp); void nexus_add_irq(u_long irq); int msi_alloc(device_t dev, int count, int maxcount, int *irqs); void msi_init(void); @@ -187,6 +183,24 @@ void xen_intr_alloc_irqs(void); #endif +/* + * Shorthand during transition away from old intrcnt_add() functionality + */ +#define INTRCNTX86_ADD(counter, msg, ...) \ + do { \ + int error; \ + \ + error = intr_event_create(counter, NULL, 0, NULL, NULL, \ + NULL, NULL, msg, __VA_ARGS__); \ + if (error != 0) \ + panic("%s(): intr_event_create() failed, return=%d", \ + __func__, error); \ + } while (0) + +typedef struct intr_event intrcntx86_t; + +#define INTRCNTX86(counter) ((counter)->ie_intrcnt) + #endif /* !LOCORE */ #endif /* _KERNEL */ #endif /* !__X86_INTR_MACHDEP_H__ */ diff --git a/sys/x86/include/x86_smp.h b/sys/x86/include/x86_smp.h --- a/sys/x86/include/x86_smp.h +++ b/sys/x86/include/x86_smp.h @@ -73,11 +73,11 @@ extern bool mwait_cpustop_broken; #ifdef COUNT_IPIS -extern u_long *ipi_invltlb_counts[MAXCPU]; -extern u_long *ipi_invlrng_counts[MAXCPU]; -extern u_long *ipi_invlpg_counts[MAXCPU]; -extern u_long *ipi_invlcache_counts[MAXCPU]; -extern u_long *ipi_rendezvous_counts[MAXCPU]; +extern intrcntx86_t *ipi_invltlb_counts[MAXCPU]; +extern intrcntx86_t *ipi_invlrng_counts[MAXCPU]; +extern intrcntx86_t *ipi_invlpg_counts[MAXCPU]; +extern intrcntx86_t *ipi_invlcache_counts[MAXCPU]; +extern intrcntx86_t *ipi_rendezvous_counts[MAXCPU]; #endif /* IPI handlers */ 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 @@ -80,7 +80,6 @@ typedef void (*mask_fn)(void *); -static int intrcnt_index; static struct intsrc **interrupt_sources; #ifdef SMP static struct intsrc **interrupt_sorted; @@ -91,7 +90,6 @@ #endif static struct sx intrsrc_lock; static struct mtx intrpic_lock; -static struct mtx intrcnt_lock; static TAILQ_HEAD(pics_head, pic) pics; u_int num_io_irqs; @@ -99,10 +97,6 @@ static int assign_cpu; #endif -u_long *intrcnt; -char *intrnames; -size_t sintrcnt = sizeof(intrcnt); -size_t sintrnames = sizeof(intrnames); int nintrcnt; static MALLOC_DEFINE(M_INTR, "intr", "Interrupt Sources"); @@ -111,9 +105,6 @@ static void intr_disable_src(void *arg); static void intr_init(void *__dummy); static int intr_pic_registered(struct pic *pic); -static void intrcnt_setname(const char *name, int index); -static void intrcnt_updatename(struct intsrc *is); -static void intrcnt_register(u_int vector, struct intsrc *is); /* * SYSINIT levels for SI_SUB_INTR: @@ -191,15 +182,6 @@ if (mp_ncpus > 1) nintrcnt += 8 * mp_ncpus; #endif - intrcnt = mallocarray(nintrcnt, sizeof(u_long), M_INTR, M_WAITOK | - M_ZERO); - intrnames = mallocarray(nintrcnt, MAXCOMLEN + 1, M_INTR, M_WAITOK | - M_ZERO); - sintrcnt = nintrcnt * sizeof(u_long); - sintrnames = nintrcnt * (MAXCOMLEN + 1); - - intrcnt_setname("???", 0); - intrcnt_index = 1; /* * NB: intrpic_lock is not held here to avoid LORs due to @@ -245,7 +227,6 @@ intr_event_destroy(isrc->is_event); return (EEXIST); } - intrcnt_register(vector, isrc); interrupt_sources[vector] = isrc; isrc->is_handlers = 0; sx_xunlock(&intrsrc_lock); @@ -272,7 +253,6 @@ arg, intr_priority(flags), flags, cookiep); if (error == 0) { sx_xlock(&intrsrc_lock); - intrcnt_updatename(isrc); isrc->is_handlers++; if (isrc->is_handlers == 1) { isrc->is_domain = domain; @@ -299,7 +279,6 @@ isrc->is_pic->pic_disable_source(isrc, PIC_NO_EOI); isrc->is_pic->pic_disable_intr(isrc); } - intrcnt_updatename(isrc); sx_xunlock(&intrsrc_lock); } return (error); @@ -334,7 +313,6 @@ * argument for counting hardware interrupts when they're * processed too. */ - (*isrc->is_count)++; VM_CNT_INC(v_intr); ie = isrc->is_event; @@ -352,14 +330,13 @@ */ if (intr_event_handle(ie, frame) != 0) { isrc->is_pic->pic_disable_source(isrc, PIC_EOI); - (*isrc->is_straycount)++; - if (*isrc->is_straycount < INTR_STRAY_LOG_MAX) + if (ie->ie_stray < INTR_STRAY_LOG_MAX) log(LOG_ERR, "stray irq%d\n", vector); - else if (*isrc->is_straycount == INTR_STRAY_LOG_MAX) + else if (ie->ie_stray == INTR_STRAY_LOG_MAX) log(LOG_CRIT, "too many stray irq %d's: not logging anymore\n", vector); - return (*isrc->is_straycount); + return (ie->ie_stray); } return (0); } @@ -426,51 +403,6 @@ #endif } -static void -intrcnt_setname(const char *name, int index) -{ - - snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s", - MAXCOMLEN, name); -} - -static void -intrcnt_updatename(struct intsrc *is) -{ - - intrcnt_setname(is->is_event->ie_fullname, is->is_index); -} - -static void -intrcnt_register(u_int vector, struct intsrc *is) -{ - char straystr[MAXCOMLEN + 1]; - - 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; - snprintf(straystr, MAXCOMLEN + 1, "stray irq%u", vector); - intrcnt_updatename(is); - is->is_count = &intrcnt[is->is_index]; - intrcnt_setname(straystr, is->is_index + 1); - is->is_straycount = &intrcnt[is->is_index + 1]; - mtx_unlock_spin(&intrcnt_lock); -} - -void -intrcnt_add(const char *name, u_long **countp) -{ - - mtx_lock_spin(&intrcnt_lock); - MPASS(intrcnt_index < nintrcnt); - *countp = &intrcnt[intrcnt_index]; - intrcnt_setname(name, intrcnt_index); - intrcnt_index++; - mtx_unlock_spin(&intrcnt_lock); -} - static void intr_init(void *dummy __unused) { @@ -478,7 +410,6 @@ TAILQ_INIT(&pics); mtx_init(&intrpic_lock, "intrpic", NULL, MTX_DEF); sx_init(&intrsrc_lock, "intrsrc"); - mtx_init(&intrcnt_lock, "intrcnt", NULL, MTX_SPIN); } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL); @@ -523,13 +454,8 @@ int intr_describe(struct intsrc *isrc, void *ih, const char *descr) { - int error; - error = intr_event_describe_handler(isrc->is_event, ih, descr); - if (error) - return (error); - intrcnt_updatename(isrc); - return (0); + return (intr_event_describe_handler(isrc->is_event, ih, descr)); } void @@ -726,12 +652,11 @@ isrc = interrupt_sources[i]; if (isrc == NULL) continue; - sbuf_printf(&sbuf, "%s:%d @cpu%d(domain%d): %ld\n", + sbuf_printf(&sbuf, "%s @cpu%d(domain%d): %lu\n", isrc->is_event->ie_fullname, - isrc->is_index, isrc->is_cpu, isrc->is_domain, - *isrc->is_count); + isrc->is_event->ie_intrcnt); } sx_sunlock(&intrsrc_lock); @@ -742,7 +667,7 @@ SYSCTL_PROC(_hw, OID_AUTO, intrs, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 0, sysctl_hw_intrs, "A", - "interrupt:number @cpu: count"); + "interrupt @cpu: count"); /* * Compare two, possibly NULL, entries in the interrupt source array @@ -756,7 +681,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) diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c @@ -143,7 +143,7 @@ u_int la_cluster:4; u_int la_cluster_id:2; u_int la_present:1; - u_long *la_timer_count; + intrcntx86_t *la_timer_count; uint64_t la_timer_period; enum lat_timer_mode la_timer_mode; uint32_t lvt_timer_base; @@ -797,7 +797,6 @@ { struct pcpu *pc; struct lapic *la; - char buf[MAXCOMLEN + 1]; /* If there are no APICs, skip this function. */ if (lapics == NULL) @@ -808,8 +807,7 @@ if (!la->la_present) continue; - snprintf(buf, sizeof(buf), "cpu%d:timer", pc->pc_cpuid); - intrcnt_add(buf, &la->la_timer_count); + INTRCNTX86_ADD(&la->la_timer_count, "cpu%d:timer", pc->pc_cpuid); } } SYSINIT(lapic_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, lapic_intrcnt, NULL); @@ -1340,7 +1338,7 @@ /* Look up our local APIC structure for the tick counters. */ la = &lapics[PCPU_GET(apic_id)]; - (*la->la_timer_count)++; + INTRCNTX86(la->la_timer_count)++; critical_enter(); if (lapic_et.et_active) { td = curthread; diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c --- a/sys/x86/x86/mp_x86.c +++ b/sys/x86/x86/mp_x86.c @@ -110,14 +110,14 @@ #ifdef COUNT_IPIS /* Interrupt counts. */ -static u_long *ipi_preempt_counts[MAXCPU]; -static u_long *ipi_ast_counts[MAXCPU]; -u_long *ipi_invltlb_counts[MAXCPU]; -u_long *ipi_invlrng_counts[MAXCPU]; -u_long *ipi_invlpg_counts[MAXCPU]; -u_long *ipi_invlcache_counts[MAXCPU]; -u_long *ipi_rendezvous_counts[MAXCPU]; -static u_long *ipi_hardclock_counts[MAXCPU]; +static struct intr_event *ipi_preempt_counts[MAXCPU]; +static struct intr_event *ipi_ast_counts[MAXCPU]; +struct intr_event *ipi_invltlb_counts[MAXCPU]; +struct intr_event *ipi_invlrng_counts[MAXCPU]; +struct intr_event *ipi_invlpg_counts[MAXCPU]; +struct intr_event *ipi_invlcache_counts[MAXCPU]; +struct intr_event *ipi_rendezvous_counts[MAXCPU]; +static struct intr_event *ipi_hardclock_counts[MAXCPU]; #endif /* Default cpu_ops implementation. */ @@ -1347,19 +1347,19 @@ #endif if (ipi_bitmap & (1 << IPI_PREEMPT)) { #ifdef COUNT_IPIS - (*ipi_preempt_counts[cpu])++; + INTRCNTX86(ipi_preempt_counts[cpu])++; #endif sched_preempt(td); } if (ipi_bitmap & (1 << IPI_AST)) { #ifdef COUNT_IPIS - (*ipi_ast_counts[cpu])++; + INTRCNTX86(ipi_ast_counts[cpu])++; #endif /* Nothing to do for AST */ } if (ipi_bitmap & (1 << IPI_HARDCLOCK)) { #ifdef COUNT_IPIS - (*ipi_hardclock_counts[cpu])++; + INTRCNTX86(ipi_hardclock_counts[cpu])++; #endif hardclockintr(); } @@ -1701,22 +1701,14 @@ int i; CPU_FOREACH(i) { - snprintf(buf, sizeof(buf), "cpu%d:invltlb", i); - intrcnt_add(buf, &ipi_invltlb_counts[i]); - snprintf(buf, sizeof(buf), "cpu%d:invlrng", i); - intrcnt_add(buf, &ipi_invlrng_counts[i]); - snprintf(buf, sizeof(buf), "cpu%d:invlpg", i); - intrcnt_add(buf, &ipi_invlpg_counts[i]); - snprintf(buf, sizeof(buf), "cpu%d:invlcache", i); - intrcnt_add(buf, &ipi_invlcache_counts[i]); - snprintf(buf, sizeof(buf), "cpu%d:preempt", i); - intrcnt_add(buf, &ipi_preempt_counts[i]); - snprintf(buf, sizeof(buf), "cpu%d:ast", i); - intrcnt_add(buf, &ipi_ast_counts[i]); - snprintf(buf, sizeof(buf), "cpu%d:rendezvous", i); - intrcnt_add(buf, &ipi_rendezvous_counts[i]); - snprintf(buf, sizeof(buf), "cpu%d:hardclock", i); - intrcnt_add(buf, &ipi_hardclock_counts[i]); + INTRCNTX86_ADD(ipi_invltlb_counts + i, "cpu%d:invltlb", i); + INTRCNTX86_ADD(ipi_invlrng_counts + i, "cpu%d:invlrng", i); + INTRCNTX86_ADD(ipi_invlpg_counts + i, "cpu%d:invlpg", i); + INTRCNTX86_ADD(ipi_invlcache_counts + i, "cpu%d:invlcache", i); + INTRCNTX86_ADD(ipi_preempt_counts + i, "cpu%d:preempt", i); + INTRCNTX86_ADD(ipi_ast_counts + i, "cpu%d:ast", i); + INTRCNTX86_ADD(ipi_rendezvous_counts + i, "cpu%d:rendezvous", i); + INTRCNTX86_ADD(ipi_hardclock_counts + i, "cpu%d:hardclock", i); } } SYSINIT(mp_ipi_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, mp_ipi_intrcnt, NULL); diff --git a/sys/x86/xen/xen_apic.c b/sys/x86/xen/xen_apic.c --- a/sys/x86/xen/xen_apic.c +++ b/sys/x86/xen/xen_apic.c @@ -234,7 +234,7 @@ xen_smp_rendezvous_action(void *arg __unused) { #ifdef COUNT_IPIS - (*ipi_rendezvous_counts[PCPU_GET(cpuid)])++; + INTRCNTX86(ipi_rendezvous_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ smp_rendezvous_action(); diff --git a/sys/x86/xen/xen_arch_intr.c b/sys/x86/xen/xen_arch_intr.c --- a/sys/x86/xen/xen_arch_intr.c +++ b/sys/x86/xen/xen_arch_intr.c @@ -56,7 +56,7 @@ /* * Pointers to the interrupt counters */ -DPCPU_DEFINE_STATIC(u_long *, pintrcnt); +DPCPU_DEFINE_STATIC(intrcntx86_t *, pintrcnt); /** * Allocate and register a per-cpu Xen upcall interrupt counter. @@ -66,15 +66,13 @@ static void xen_intr_intrcnt_add(const u_int cpu) { - char buf[MAXCOMLEN + 1]; - u_long **ppintrcnt; + intrcntx86_t **ppintrcnt; ppintrcnt = DPCPU_ID_PTR(cpu, pintrcnt); if (ppintrcnt != NULL) return; - snprintf(buf, sizeof(buf), "cpu%d:xen", cpu); - intrcnt_add(buf, ppintrcnt); + INTRCNTX86_ADD(ppintrcnt, "cpu%d:xen", cpu); } static void @@ -110,7 +108,7 @@ */ critical_enter(); - ++*DPCPU_GET(pintrcnt); + ++INTRCNTX86(DPCPU_GET(pintrcnt)); old = curthread->td_intr_frame; curthread->td_intr_frame = trap_frame;