Commit 4a1dba72 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'urgent' of git://amd64.org/linux/rric into perf/urgent

parents ed13ec58 97f7f818
...@@ -21,6 +21,7 @@ extern int op_nmi_timer_init(struct oprofile_operations *ops); ...@@ -21,6 +21,7 @@ extern int op_nmi_timer_init(struct oprofile_operations *ops);
extern void op_nmi_exit(void); extern void op_nmi_exit(void);
extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth); extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth);
static int nmi_timer;
int __init oprofile_arch_init(struct oprofile_operations *ops) int __init oprofile_arch_init(struct oprofile_operations *ops)
{ {
...@@ -31,8 +32,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ...@@ -31,8 +32,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
ret = op_nmi_init(ops); ret = op_nmi_init(ops);
#endif #endif
nmi_timer = (ret != 0);
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
if (ret < 0) if (nmi_timer)
ret = op_nmi_timer_init(ops); ret = op_nmi_timer_init(ops);
#endif #endif
ops->backtrace = x86_backtrace; ops->backtrace = x86_backtrace;
...@@ -44,6 +46,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ...@@ -44,6 +46,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
void oprofile_arch_exit(void) void oprofile_arch_exit(void)
{ {
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
if (!nmi_timer)
op_nmi_exit(); op_nmi_exit();
#endif #endif
} }
...@@ -239,25 +239,44 @@ int oprofile_set_ulong(unsigned long *addr, unsigned long val) ...@@ -239,25 +239,44 @@ int oprofile_set_ulong(unsigned long *addr, unsigned long val)
return err; return err;
} }
static int timer_mode;
static int __init oprofile_init(void) static int __init oprofile_init(void)
{ {
int err; int err;
/* always init architecture to setup backtrace support */
err = oprofile_arch_init(&oprofile_ops); err = oprofile_arch_init(&oprofile_ops);
if (err < 0 || timer) {
printk(KERN_INFO "oprofile: using timer interrupt.\n"); timer_mode = err || timer; /* fall back to timer mode on errors */
if (timer_mode) {
if (!err)
oprofile_arch_exit();
err = oprofile_timer_init(&oprofile_ops); err = oprofile_timer_init(&oprofile_ops);
if (err) if (err)
return err; return err;
} }
return oprofilefs_register();
err = oprofilefs_register();
if (!err)
return 0;
/* failed */
if (timer_mode)
oprofile_timer_exit();
else
oprofile_arch_exit();
return err;
} }
static void __exit oprofile_exit(void) static void __exit oprofile_exit(void)
{ {
oprofile_timer_exit();
oprofilefs_unregister(); oprofilefs_unregister();
if (timer_mode)
oprofile_timer_exit();
else
oprofile_arch_exit(); oprofile_arch_exit();
} }
......
...@@ -110,6 +110,7 @@ int oprofile_timer_init(struct oprofile_operations *ops) ...@@ -110,6 +110,7 @@ int oprofile_timer_init(struct oprofile_operations *ops)
ops->start = oprofile_hrtimer_start; ops->start = oprofile_hrtimer_start;
ops->stop = oprofile_hrtimer_stop; ops->stop = oprofile_hrtimer_stop;
ops->cpu_type = "timer"; ops->cpu_type = "timer";
printk(KERN_INFO "oprofile: using timer interrupt.\n");
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment