diff options
author | Ingo Molnar <mingo@elte.hu> | 2011-11-15 05:03:30 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-11-15 05:03:30 -0500 |
commit | 4a1dba72384193753e44e15d9d05a50be6587271 (patch) | |
tree | a4fc4caa6a11413463b59d8521b67e3cb3926320 | |
parent | ed13ec58bfe0d5dc95f748e6118432cb0fa283cb (diff) | |
parent | 97f7f8189fe54e3cfe324ef9ad35064f3d2d3bff (diff) |
Merge branch 'urgent' of git://amd64.org/linux/rric into perf/urgent
-rw-r--r-- | arch/x86/oprofile/init.c | 7 | ||||
-rw-r--r-- | drivers/oprofile/oprof.c | 29 | ||||
-rw-r--r-- | drivers/oprofile/timer_int.c | 1 |
3 files changed, 30 insertions, 7 deletions
diff --git a/arch/x86/oprofile/init.c b/arch/x86/oprofile/init.c index cdfe4c54deca..f148cf652678 100644 --- a/arch/x86/oprofile/init.c +++ b/arch/x86/oprofile/init.c | |||
@@ -21,6 +21,7 @@ extern int op_nmi_timer_init(struct oprofile_operations *ops); | |||
21 | extern void op_nmi_exit(void); | 21 | extern void op_nmi_exit(void); |
22 | extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth); | 22 | extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth); |
23 | 23 | ||
24 | static int nmi_timer; | ||
24 | 25 | ||
25 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 26 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
26 | { | 27 | { |
@@ -31,8 +32,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
31 | #ifdef CONFIG_X86_LOCAL_APIC | 32 | #ifdef CONFIG_X86_LOCAL_APIC |
32 | ret = op_nmi_init(ops); | 33 | ret = op_nmi_init(ops); |
33 | #endif | 34 | #endif |
35 | nmi_timer = (ret != 0); | ||
34 | #ifdef CONFIG_X86_IO_APIC | 36 | #ifdef CONFIG_X86_IO_APIC |
35 | if (ret < 0) | 37 | if (nmi_timer) |
36 | ret = op_nmi_timer_init(ops); | 38 | ret = op_nmi_timer_init(ops); |
37 | #endif | 39 | #endif |
38 | ops->backtrace = x86_backtrace; | 40 | ops->backtrace = x86_backtrace; |
@@ -44,6 +46,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
44 | void oprofile_arch_exit(void) | 46 | void oprofile_arch_exit(void) |
45 | { | 47 | { |
46 | #ifdef CONFIG_X86_LOCAL_APIC | 48 | #ifdef CONFIG_X86_LOCAL_APIC |
47 | op_nmi_exit(); | 49 | if (!nmi_timer) |
50 | op_nmi_exit(); | ||
48 | #endif | 51 | #endif |
49 | } | 52 | } |
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index dccd8636095c..f8c752e408a6 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c | |||
@@ -239,26 +239,45 @@ int oprofile_set_ulong(unsigned long *addr, unsigned long val) | |||
239 | return err; | 239 | return err; |
240 | } | 240 | } |
241 | 241 | ||
242 | static int timer_mode; | ||
243 | |||
242 | static int __init oprofile_init(void) | 244 | static int __init oprofile_init(void) |
243 | { | 245 | { |
244 | int err; | 246 | int err; |
245 | 247 | ||
248 | /* always init architecture to setup backtrace support */ | ||
246 | err = oprofile_arch_init(&oprofile_ops); | 249 | err = oprofile_arch_init(&oprofile_ops); |
247 | if (err < 0 || timer) { | 250 | |
248 | printk(KERN_INFO "oprofile: using timer interrupt.\n"); | 251 | timer_mode = err || timer; /* fall back to timer mode on errors */ |
252 | if (timer_mode) { | ||
253 | if (!err) | ||
254 | oprofile_arch_exit(); | ||
249 | err = oprofile_timer_init(&oprofile_ops); | 255 | err = oprofile_timer_init(&oprofile_ops); |
250 | if (err) | 256 | if (err) |
251 | return err; | 257 | return err; |
252 | } | 258 | } |
253 | return oprofilefs_register(); | 259 | |
260 | err = oprofilefs_register(); | ||
261 | if (!err) | ||
262 | return 0; | ||
263 | |||
264 | /* failed */ | ||
265 | if (timer_mode) | ||
266 | oprofile_timer_exit(); | ||
267 | else | ||
268 | oprofile_arch_exit(); | ||
269 | |||
270 | return err; | ||
254 | } | 271 | } |
255 | 272 | ||
256 | 273 | ||
257 | static void __exit oprofile_exit(void) | 274 | static void __exit oprofile_exit(void) |
258 | { | 275 | { |
259 | oprofile_timer_exit(); | ||
260 | oprofilefs_unregister(); | 276 | oprofilefs_unregister(); |
261 | oprofile_arch_exit(); | 277 | if (timer_mode) |
278 | oprofile_timer_exit(); | ||
279 | else | ||
280 | oprofile_arch_exit(); | ||
262 | } | 281 | } |
263 | 282 | ||
264 | 283 | ||
diff --git a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c index 3ef44624f510..878fba126582 100644 --- a/drivers/oprofile/timer_int.c +++ b/drivers/oprofile/timer_int.c | |||
@@ -110,6 +110,7 @@ int oprofile_timer_init(struct oprofile_operations *ops) | |||
110 | ops->start = oprofile_hrtimer_start; | 110 | ops->start = oprofile_hrtimer_start; |
111 | ops->stop = oprofile_hrtimer_stop; | 111 | ops->stop = oprofile_hrtimer_stop; |
112 | ops->cpu_type = "timer"; | 112 | ops->cpu_type = "timer"; |
113 | printk(KERN_INFO "oprofile: using timer interrupt.\n"); | ||
113 | return 0; | 114 | return 0; |
114 | } | 115 | } |
115 | 116 | ||