aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/cpu/perf_event.c12
-rw-r--r--arch/x86/kernel/cpu/perf_event_p4.c6
3 files changed, 18 insertions, 2 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 24fa1718ddb9..9d3f485e5dd0 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -11,6 +11,8 @@ ifdef CONFIG_FUNCTION_TRACER
11CFLAGS_REMOVE_tsc.o = -pg 11CFLAGS_REMOVE_tsc.o = -pg
12CFLAGS_REMOVE_rtc.o = -pg 12CFLAGS_REMOVE_rtc.o = -pg
13CFLAGS_REMOVE_paravirt-spinlocks.o = -pg 13CFLAGS_REMOVE_paravirt-spinlocks.o = -pg
14CFLAGS_REMOVE_pvclock.o = -pg
15CFLAGS_REMOVE_kvmclock.o = -pg
14CFLAGS_REMOVE_ftrace.o = -pg 16CFLAGS_REMOVE_ftrace.o = -pg
15CFLAGS_REMOVE_early_printk.o = -pg 17CFLAGS_REMOVE_early_printk.o = -pg
16endif 18endif
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 0fb17050360f..6526a86616a7 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -102,6 +102,7 @@ struct cpu_hw_events {
102 */ 102 */
103 struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */ 103 struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */
104 unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; 104 unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
105 unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
105 int enabled; 106 int enabled;
106 107
107 int n_events; 108 int n_events;
@@ -1034,6 +1035,7 @@ static void x86_pmu_start(struct perf_event *event, int flags)
1034 1035
1035 cpuc->events[idx] = event; 1036 cpuc->events[idx] = event;
1036 __set_bit(idx, cpuc->active_mask); 1037 __set_bit(idx, cpuc->active_mask);
1038 __set_bit(idx, cpuc->running);
1037 x86_pmu.enable(event); 1039 x86_pmu.enable(event);
1038 perf_event_update_userpage(event); 1040 perf_event_update_userpage(event);
1039} 1041}
@@ -1159,8 +1161,16 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
1159 cpuc = &__get_cpu_var(cpu_hw_events); 1161 cpuc = &__get_cpu_var(cpu_hw_events);
1160 1162
1161 for (idx = 0; idx < x86_pmu.num_counters; idx++) { 1163 for (idx = 0; idx < x86_pmu.num_counters; idx++) {
1162 if (!test_bit(idx, cpuc->active_mask)) 1164 if (!test_bit(idx, cpuc->active_mask)) {
1165 /*
1166 * Though we deactivated the counter some cpus
1167 * might still deliver spurious interrupts still
1168 * in flight. Catch them:
1169 */
1170 if (__test_and_clear_bit(idx, cpuc->running))
1171 handled++;
1163 continue; 1172 continue;
1173 }
1164 1174
1165 event = cpuc->events[idx]; 1175 event = cpuc->events[idx];
1166 hwc = &event->hw; 1176 hwc = &event->hw;
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c
index c70c878ee02a..81400b93e694 100644
--- a/arch/x86/kernel/cpu/perf_event_p4.c
+++ b/arch/x86/kernel/cpu/perf_event_p4.c
@@ -904,8 +904,12 @@ static int p4_pmu_handle_irq(struct pt_regs *regs)
904 for (idx = 0; idx < x86_pmu.num_counters; idx++) { 904 for (idx = 0; idx < x86_pmu.num_counters; idx++) {
905 int overflow; 905 int overflow;
906 906
907 if (!test_bit(idx, cpuc->active_mask)) 907 if (!test_bit(idx, cpuc->active_mask)) {
908 /* catch in-flight IRQs */
909 if (__test_and_clear_bit(idx, cpuc->running))
910 handled++;
908 continue; 911 continue;
912 }
909 913
910 event = cpuc->events[idx]; 914 event = cpuc->events[idx];
911 hwc = &event->hw; 915 hwc = &event->hw;