diff options
author | John Baldwin <jhb@FreeBSD.org> | 2005-09-28 18:04:11 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2005-09-28 18:04:11 +0000 |
commit | 29442a30e282fd886a9a37fd036072d2b4e6731f (patch) | |
tree | 6b90ed4a968a4ca5bc8f2471666f9582e69dd326 /sys/i386 | |
parent | ea688ef40b1d310e9aa0001baab9069000bcb89c (diff) | |
download | src-29442a30e282fd886a9a37fd036072d2b4e6731f.tar.gz src-29442a30e282fd886a9a37fd036072d2b4e6731f.zip |
Add interrupt counters for IPIs. By default they are disabled, but they
can be enabled by enabling COUNT_IPIS in smptests.h. When enabled, each
CPU provides an interrupt counter for nearly all of the IPIs it receives
(IPI_STOP currently doesn't have a counter) that can be examined using
vmstat -i, etc.
MFC after: 3 days
Requested by: rwatson
Notes
Notes:
svn path=/head/; revision=150697
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/i386/apic_vector.s | 40 | ||||
-rw-r--r-- | sys/i386/i386/mp_machdep.c | 57 | ||||
-rw-r--r-- | sys/i386/include/smptests.h | 8 |
3 files changed, 97 insertions, 8 deletions
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index c770bcf4be6e..99b765f1519c 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -151,14 +151,20 @@ IDTVEC(invltlb) movl $KDSEL, %eax /* Kernel data selector */ movl %eax, %ds -#ifdef COUNT_XINVLTLB_HITS +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) pushl %fs movl $KPSEL, %eax /* Private space selector */ movl %eax, %fs movl PCPU(CPUID), %eax popl %fs +#ifdef COUNT_XINVLTLB_HITS incl xhits_gbl(,%eax,4) -#endif /* COUNT_XINVLTLB_HITS */ +#endif +#ifdef COUNT_IPIS + movl ipi_invltlb_counts(,%eax,4),%eax + incl (%eax) +#endif +#endif movl %cr3, %eax /* invalidate the TLB */ movl %eax, %cr3 @@ -184,14 +190,20 @@ IDTVEC(invlpg) movl $KDSEL, %eax /* Kernel data selector */ movl %eax, %ds -#ifdef COUNT_XINVLTLB_HITS +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) pushl %fs movl $KPSEL, %eax /* Private space selector */ movl %eax, %fs movl PCPU(CPUID), %eax popl %fs +#ifdef COUNT_XINVLTLB_HITS incl xhits_pg(,%eax,4) -#endif /* COUNT_XINVLTLB_HITS */ +#endif +#ifdef COUNT_IPIS + movl ipi_invlpg_counts(,%eax,4),%eax + incl (%eax) +#endif +#endif movl smp_tlb_addr1, %eax invlpg (%eax) /* invalidate single page */ @@ -218,14 +230,20 @@ IDTVEC(invlrng) movl $KDSEL, %eax /* Kernel data selector */ movl %eax, %ds -#ifdef COUNT_XINVLTLB_HITS +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) pushl %fs movl $KPSEL, %eax /* Private space selector */ movl %eax, %fs movl PCPU(CPUID), %eax popl %fs +#ifdef COUNT_XINVLTLB_HITS incl xhits_rng(,%eax,4) -#endif /* COUNT_XINVLTLB_HITS */ +#endif +#ifdef COUNT_IPIS + movl ipi_invlrng_counts(,%eax,4),%eax + incl (%eax) +#endif +#endif movl smp_tlb_addr1, %edx movl smp_tlb_addr2, %eax @@ -354,6 +372,11 @@ IDTVEC(rendezvous) movl $KPSEL, %eax movl %eax, %fs +#ifdef COUNT_IPIS + movl PCPU(CPUID), %eax + movl ipi_rendezvous_counts(,%eax,4), %eax + incl (%eax) +#endif call smp_rendezvous_action movl lapic, %eax @@ -374,6 +397,11 @@ IDTVEC(lazypmap) movl $KPSEL, %eax movl %eax, %fs +#ifdef COUNT_IPIS + movl PCPU(CPUID), %eax + movl ipi_lazypmap_counts(,%eax,4), %eax + incl (%eax) +#endif call pmap_lazyfix_action movl lapic, %eax diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 4873946214cf..aeb79bd6e161 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -181,6 +181,19 @@ volatile int smp_tlb_wait; volatile cpumask_t ipi_nmi_pending; #endif +#ifdef COUNT_IPIS +/* Interrupt counts. */ +#ifdef IPI_PREEMPTION +static u_long *ipi_preempt_counts[MAXCPU]; +#endif +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_rendezvous_counts[MAXCPU]; +u_long *ipi_lazypmap_counts[MAXCPU]; +#endif + /* * Local data and functions. */ @@ -1130,6 +1143,9 @@ ipi_bitmap_handler(struct clockframe frame) #ifdef IPI_PREEMPTION if (ipi_bitmap & IPI_PREEMPT) { +#ifdef COUNT_IPIS + *ipi_preempt_counts[cpu]++; +#endif mtx_lock_spin(&sched_lock); /* Don't preempt the idle thread */ if (curthread->td_priority < PRI_MIN_IDLE) { @@ -1143,7 +1159,12 @@ ipi_bitmap_handler(struct clockframe frame) } #endif - /* Nothing to do for AST */ + if (ipi_bitmap & IPI_AST) { +#ifdef COUNT_IPIS + *ipi_ast_counts[cpu]++; +#endif + /* Nothing to do for AST */ + } } /* @@ -1445,3 +1466,37 @@ mp_grab_cpu_hlt(void) __asm __volatile("sti; hlt" : : : "memory"); return (retval); } + +#ifdef COUNT_IPIS +/* + * Setup interrupt counters for IPI handlers. + */ +static void +mp_ipi_intrcnt(void *dummy) +{ + char buf[64]; + int i; + + for (i = 0; i < mp_maxid; i++) { + if (CPU_ABSENT(i)) + continue; + 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]); +#ifdef IPI_PREEMPTION + snprintf(buf, sizeof(buf), "cpu%d: preempt", i); + intrcnt_add(buf, &ipi_preempt_counts[i]); +#endif + 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: lazypmap", i); + intrcnt_add(buf, &ipi_lazypmap_counts[i]); + } +} +SYSINIT(mp_ipi_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, mp_ipi_intrcnt, NULL) +#endif diff --git a/sys/i386/include/smptests.h b/sys/i386/include/smptests.h index e25c22692483..3d60740b75d0 100644 --- a/sys/i386/include/smptests.h +++ b/sys/i386/include/smptests.h @@ -40,12 +40,18 @@ #define CPUSTOP_ON_DDBBREAK /* - * Misc. counters. + * TLB counters. * #define COUNT_XINVLTLB_HITS */ /* + * Per-CPU IPI interrupt counters. + * +#define COUNT_IPIS + */ + +/* * Address of POST hardware port. * Defining this enables POSTCODE macros. * |