summaryrefslogtreecommitdiff
path: root/sys/dev/hwpmc
diff options
context:
space:
mode:
authorJoseph Koshy <jkoshy@FreeBSD.org>2005-09-12 15:55:44 +0000
committerJoseph Koshy <jkoshy@FreeBSD.org>2005-09-12 15:55:44 +0000
commitbebaef4a3d07213f7b39e42df0fd1f6512439c58 (patch)
tree3ca797e9d2b629a6d0489f0ac1052b1aa12b27e8 /sys/dev/hwpmc
parent533dcdacf1b8f5e19ebb6511f2e2690dbae5fb17 (diff)
Notes
Diffstat (limited to 'sys/dev/hwpmc')
-rw-r--r--sys/dev/hwpmc/hwpmc_amd.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c
index 6285f7fd75bab..3d92829863900 100644
--- a/sys/dev/hwpmc/hwpmc_amd.c
+++ b/sys/dev/hwpmc/hwpmc_amd.c
@@ -693,9 +693,14 @@ amd_intr(int cpu, uintptr_t eip, int usermode)
* and which has a valid 'struct pmc' association
*
* If found, we call a helper to process the interrupt.
+ *
+ * If multiple PMCs interrupt at the same time, the AMD64
+ * processor appears to deliver as many NMIs as there are
+ * outstanding PMC interrupts. Thus we need to only process
+ * one interrupt at a time.
*/
- for (i = 0; i < AMD_NPMCS-1; i++) {
+ for (i = 0; retval == 0 && i < AMD_NPMCS-1; i++) {
ri = i + 1; /* row index; TSC is at ri == 0 */
@@ -712,6 +717,8 @@ amd_intr(int cpu, uintptr_t eip, int usermode)
continue;
}
+ retval = 1; /* found an interrupting PMC */
+
/* stop the PMC, reload count */
evsel = AMD_PMC_EVSEL_0 + i;
perfctr = AMD_PMC_PERFCTR_0 + i;
@@ -726,12 +733,10 @@ amd_intr(int cpu, uintptr_t eip, int usermode)
wrmsr(evsel, config & ~AMD_PMC_ENABLE);
wrmsr(perfctr, AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v));
- /* restart if there was no error during logging */
+ /* restart the counter if there was no error during logging */
error = pmc_process_interrupt(cpu, pm, eip, usermode);
if (error == 0)
wrmsr(evsel, config | AMD_PMC_ENABLE);
-
- retval = 1; /* found an interrupting PMC */
}
atomic_add_int(retval ? &pmc_stats.pm_intr_processed :