aboutsummaryrefslogtreecommitdiff
path: root/sys/i386
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2005-09-28 18:04:11 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2005-09-28 18:04:11 +0000
commit29442a30e282fd886a9a37fd036072d2b4e6731f (patch)
tree6b90ed4a968a4ca5bc8f2471666f9582e69dd326 /sys/i386
parentea688ef40b1d310e9aa0001baab9069000bcb89c (diff)
downloadsrc-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.s40
-rw-r--r--sys/i386/i386/mp_machdep.c57
-rw-r--r--sys/i386/include/smptests.h8
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.
*