aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/oprofile/common.c7
-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
-rw-r--r--arch/x86/oprofile/nmi_int.c1
5 files changed, 24 insertions, 4 deletions
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index aad63e611b36..d1fb5b2f5218 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -102,6 +102,7 @@ static int op_create_counter(int cpu, int event)
102 if (IS_ERR(pevent)) { 102 if (IS_ERR(pevent)) {
103 ret = PTR_ERR(pevent); 103 ret = PTR_ERR(pevent);
104 } else if (pevent->state != PERF_EVENT_STATE_ACTIVE) { 104 } else if (pevent->state != PERF_EVENT_STATE_ACTIVE) {
105 perf_event_release_kernel(pevent);
105 pr_warning("oprofile: failed to enable event %d " 106 pr_warning("oprofile: failed to enable event %d "
106 "on CPU %d\n", event, cpu); 107 "on CPU %d\n", event, cpu);
107 ret = -EBUSY; 108 ret = -EBUSY;
@@ -365,6 +366,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
365 ret = init_driverfs(); 366 ret = init_driverfs();
366 if (ret) { 367 if (ret) {
367 kfree(counter_config); 368 kfree(counter_config);
369 counter_config = NULL;
368 return ret; 370 return ret;
369 } 371 }
370 372
@@ -402,7 +404,6 @@ void oprofile_arch_exit(void)
402 struct perf_event *event; 404 struct perf_event *event;
403 405
404 if (*perf_events) { 406 if (*perf_events) {
405 exit_driverfs();
406 for_each_possible_cpu(cpu) { 407 for_each_possible_cpu(cpu) {
407 for (id = 0; id < perf_num_counters; ++id) { 408 for (id = 0; id < perf_num_counters; ++id) {
408 event = perf_events[cpu][id]; 409 event = perf_events[cpu][id];
@@ -413,8 +414,10 @@ void oprofile_arch_exit(void)
413 } 414 }
414 } 415 }
415 416
416 if (counter_config) 417 if (counter_config) {
417 kfree(counter_config); 418 kfree(counter_config);
419 exit_driverfs();
420 }
418} 421}
419#else 422#else
420int __init oprofile_arch_init(struct oprofile_operations *ops) 423int __init oprofile_arch_init(struct oprofile_operations *ops)
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;
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 009b819f48d0..f1575c9a2572 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -674,6 +674,7 @@ static int __init ppro_init(char **cpu_type)
674 case 0x0f: 674 case 0x0f:
675 case 0x16: 675 case 0x16:
676 case 0x17: 676 case 0x17:
677 case 0x1d:
677 *cpu_type = "i386/core_2"; 678 *cpu_type = "i386/core_2";
678 break; 679 break;
679 case 0x1a: 680 case 0x1a: