aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2010-03-06 07:20:40 -0500
committerIngo Molnar <mingo@elte.hu>2010-03-10 07:22:33 -0500
commit19925ce778f9fc371b9607625de3bff04c60121e (patch)
tree727f1c39252fd99e7f58d9355b19d49578f5cad6 /arch/x86/kernel/cpu
parent356e1f2e0ace2d4b100c8eda9d49b709e8323da5 (diff)
perf, x86: Fix double disable calls
hw_perf_enable() would disable events that were not yet enabled. This causes problems with code that assumes that ->enable/->disable calls are balanced (like the LBR code does). What happens is that we disable newly added counters that match their previous assignment, even though they are not yet programmed on the hardware. Avoid this by only doing the first pass over the existing events. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@infradead.org> Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/cpu')
-rw-r--r--arch/x86/kernel/cpu/perf_event.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 071c8405debd..045cc0bb4c17 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -802,6 +802,7 @@ void hw_perf_enable(void)
802 return; 802 return;
803 803
804 if (cpuc->n_added) { 804 if (cpuc->n_added) {
805 int n_running = cpuc->n_events - cpuc->n_added;
805 /* 806 /*
806 * apply assignment obtained either from 807 * apply assignment obtained either from
807 * hw_perf_group_sched_in() or x86_pmu_enable() 808 * hw_perf_group_sched_in() or x86_pmu_enable()
@@ -809,7 +810,7 @@ void hw_perf_enable(void)
809 * step1: save events moving to new counters 810 * step1: save events moving to new counters
810 * step2: reprogram moved events into new counters 811 * step2: reprogram moved events into new counters
811 */ 812 */
812 for (i = 0; i < cpuc->n_events; i++) { 813 for (i = 0; i < n_running; i++) {
813 814
814 event = cpuc->event_list[i]; 815 event = cpuc->event_list[i];
815 hwc = &event->hw; 816 hwc = &event->hw;