diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2010-11-25 12:38:29 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-11-26 09:14:56 -0500 |
commit | 004417a6d468e24399e383645c068b498eed84ad (patch) | |
tree | ce3f4ea25186080faec7a7be6648b177e526c436 /arch/x86 | |
parent | 5ef428c4b5950dddce7311e84321abb3aff7ebb0 (diff) |
perf, arch: Cleanup perf-pmu init vs lockup-detector
The perf hardware pmu got initialized at various points in the boot,
some before early_initcall() some after (notably arch_initcall).
The problem is that the NMI lockup detector is ran from early_initcall()
and expects the hardware pmu to be present.
Sanitize this by moving all architecture hardware pmu implementations to
initialize at early_initcall() and move the lockup detector to an explicit
initcall right after that.
Cc: paulus <paulus@samba.org>
Cc: davem <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1290707759.2145.119.camel@laptop>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/perf_event.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 11 |
3 files changed, 7 insertions, 7 deletions
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 550e26b1dbb3..d9d4dae305f6 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h | |||
@@ -125,7 +125,6 @@ union cpuid10_edx { | |||
125 | #define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */ | 125 | #define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */ |
126 | 126 | ||
127 | #ifdef CONFIG_PERF_EVENTS | 127 | #ifdef CONFIG_PERF_EVENTS |
128 | extern void init_hw_perf_events(void); | ||
129 | extern void perf_events_lapic_init(void); | 128 | extern void perf_events_lapic_init(void); |
130 | 129 | ||
131 | #define PERF_EVENT_INDEX_OFFSET 0 | 130 | #define PERF_EVENT_INDEX_OFFSET 0 |
@@ -156,7 +155,6 @@ extern unsigned long perf_misc_flags(struct pt_regs *regs); | |||
156 | } | 155 | } |
157 | 156 | ||
158 | #else | 157 | #else |
159 | static inline void init_hw_perf_events(void) { } | ||
160 | static inline void perf_events_lapic_init(void) { } | 158 | static inline void perf_events_lapic_init(void) { } |
161 | #endif | 159 | #endif |
162 | 160 | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 4b68bda30938..1d59834396bd 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -894,7 +894,6 @@ void __init identify_boot_cpu(void) | |||
894 | #else | 894 | #else |
895 | vgetcpu_set_mode(); | 895 | vgetcpu_set_mode(); |
896 | #endif | 896 | #endif |
897 | init_hw_perf_events(); | ||
898 | } | 897 | } |
899 | 898 | ||
900 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) | 899 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index c01dfec635db..817d2b195e8e 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -1353,7 +1353,7 @@ static void __init pmu_check_apic(void) | |||
1353 | pr_info("no hardware sampling interrupt available.\n"); | 1353 | pr_info("no hardware sampling interrupt available.\n"); |
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | void __init init_hw_perf_events(void) | 1356 | int __init init_hw_perf_events(void) |
1357 | { | 1357 | { |
1358 | struct event_constraint *c; | 1358 | struct event_constraint *c; |
1359 | int err; | 1359 | int err; |
@@ -1368,11 +1368,11 @@ void __init init_hw_perf_events(void) | |||
1368 | err = amd_pmu_init(); | 1368 | err = amd_pmu_init(); |
1369 | break; | 1369 | break; |
1370 | default: | 1370 | default: |
1371 | return; | 1371 | return 0; |
1372 | } | 1372 | } |
1373 | if (err != 0) { | 1373 | if (err != 0) { |
1374 | pr_cont("no PMU driver, software events only.\n"); | 1374 | pr_cont("no PMU driver, software events only.\n"); |
1375 | return; | 1375 | return 0; |
1376 | } | 1376 | } |
1377 | 1377 | ||
1378 | pmu_check_apic(); | 1378 | pmu_check_apic(); |
@@ -1380,7 +1380,7 @@ void __init init_hw_perf_events(void) | |||
1380 | /* sanity check that the hardware exists or is emulated */ | 1380 | /* sanity check that the hardware exists or is emulated */ |
1381 | if (!check_hw_exists()) { | 1381 | if (!check_hw_exists()) { |
1382 | pr_cont("Broken PMU hardware detected, software events only.\n"); | 1382 | pr_cont("Broken PMU hardware detected, software events only.\n"); |
1383 | return; | 1383 | return 0; |
1384 | } | 1384 | } |
1385 | 1385 | ||
1386 | pr_cont("%s PMU driver.\n", x86_pmu.name); | 1386 | pr_cont("%s PMU driver.\n", x86_pmu.name); |
@@ -1431,7 +1431,10 @@ void __init init_hw_perf_events(void) | |||
1431 | 1431 | ||
1432 | perf_pmu_register(&pmu); | 1432 | perf_pmu_register(&pmu); |
1433 | perf_cpu_notifier(x86_pmu_notifier); | 1433 | perf_cpu_notifier(x86_pmu_notifier); |
1434 | |||
1435 | return 0; | ||
1434 | } | 1436 | } |
1437 | early_initcall(init_hw_perf_events); | ||
1435 | 1438 | ||
1436 | static inline void x86_pmu_read(struct perf_event *event) | 1439 | static inline void x86_pmu_read(struct perf_event *event) |
1437 | { | 1440 | { |