summaryrefslogtreecommitdiff
path: root/drivers/oprofile
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2011-11-15 11:03:30 +0100
committerIngo Molnar <mingo@elte.hu>2011-11-15 11:03:30 +0100
commit4a1dba72384193753e44e15d9d05a50be6587271 (patch)
treea4fc4caa6a11413463b59d8521b67e3cb3926320 /drivers/oprofile
parented13ec58bfe0d5dc95f748e6118432cb0fa283cb (diff)
parent97f7f8189fe54e3cfe324ef9ad35064f3d2d3bff (diff)
downloadkernel-4a1dba72384193753e44e15d9d05a50be6587271.tar.gz
Merge branch 'urgent' of git://amd64.org/linux/rric into perf/urgent
Diffstat (limited to 'drivers/oprofile')
-rw-r--r--drivers/oprofile/oprof.c29
-rw-r--r--drivers/oprofile/timer_int.c1
2 files changed, 25 insertions, 5 deletions
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)
return err;
}
+static int timer_mode;
+
static int __init oprofile_init(void)
{
int err;
+ /* always init architecture to setup backtrace support */
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);
if (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)
{
- oprofile_timer_exit();
oprofilefs_unregister();
- oprofile_arch_exit();
+ if (timer_mode)
+ oprofile_timer_exit();
+ else
+ oprofile_arch_exit();
}
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)
ops->start = oprofile_hrtimer_start;
ops->stop = oprofile_hrtimer_stop;
ops->cpu_type = "timer";
+ printk(KERN_INFO "oprofile: using timer interrupt.\n");
return 0;
}