X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Foprofile%2Foprof.c;h=b82a7b5aaa740520932ade8d84110be5495c13ea;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=a85d33dec8c42b9a636eac62260aeaafa8ec4ca0;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index a85d33dec..b82a7b5aa 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c @@ -5,6 +5,10 @@ * @remark Read the file COPYING * * @author John Levon + * + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include @@ -12,18 +16,20 @@ #include #include #include -#include +#include #include "oprof.h" #include "event_buffer.h" #include "cpu_buffer.h" #include "buffer_sync.h" #include "oprofile_stats.h" - -struct oprofile_operations * oprofile_ops; + +struct oprofile_operations oprofile_ops; + unsigned long oprofile_started; +unsigned long backtrace_depth; static unsigned long is_setup; -static DECLARE_MUTEX(start_sem); +static DEFINE_MUTEX(start_mutex); /* timer 0 - use performance monitoring hardware if available @@ -31,11 +37,37 @@ static DECLARE_MUTEX(start_sem); */ static int timer = 0; +int oprofile_set_active(int active_domains[], unsigned int adomains) +{ + int err; + + if (!oprofile_ops.set_active) + return -EINVAL; + + mutex_lock(&start_mutex); + err = oprofile_ops.set_active(active_domains, adomains); + mutex_unlock(&start_mutex); + return err; +} + +int oprofile_set_passive(int passive_domains[], unsigned int pdomains) +{ + int err; + + if (!oprofile_ops.set_passive) + return -EINVAL; + + mutex_lock(&start_mutex); + err = oprofile_ops.set_passive(passive_domains, pdomains); + mutex_unlock(&start_mutex); + return err; +} + int oprofile_setup(void) { int err; - down(&start_sem); + mutex_lock(&start_mutex); if ((err = alloc_cpu_buffers())) goto out; @@ -43,7 +75,7 @@ int oprofile_setup(void) if ((err = alloc_event_buffer())) goto out1; - if (oprofile_ops->setup && (err = oprofile_ops->setup())) + if (oprofile_ops.setup && (err = oprofile_ops.setup())) goto out2; /* Note even though this starts part of the @@ -55,18 +87,18 @@ int oprofile_setup(void) goto out3; is_setup = 1; - up(&start_sem); + mutex_unlock(&start_mutex); return 0; out3: - if (oprofile_ops->shutdown) - oprofile_ops->shutdown(); + if (oprofile_ops.shutdown) + oprofile_ops.shutdown(); out2: free_event_buffer(); out1: free_cpu_buffers(); out: - up(&start_sem); + mutex_unlock(&start_mutex); return err; } @@ -76,7 +108,7 @@ int oprofile_start(void) { int err = -EINVAL; - down(&start_sem); + mutex_lock(&start_mutex); if (!is_setup) goto out; @@ -88,12 +120,12 @@ int oprofile_start(void) oprofile_reset_stats(); - if ((err = oprofile_ops->start())) + if ((err = oprofile_ops.start())) goto out; oprofile_started = 1; out: - up(&start_sem); + mutex_unlock(&start_mutex); return err; } @@ -101,63 +133,70 @@ out: /* echo 0>/dev/oprofile/enable */ void oprofile_stop(void) { - down(&start_sem); + mutex_lock(&start_mutex); if (!oprofile_started) goto out; - oprofile_ops->stop(); + oprofile_ops.stop(); oprofile_started = 0; /* wake up the daemon to read what remains */ wake_up_buffer_waiter(); out: - up(&start_sem); + mutex_unlock(&start_mutex); } void oprofile_shutdown(void) { - down(&start_sem); + mutex_lock(&start_mutex); sync_stop(); - if (oprofile_ops->shutdown) - oprofile_ops->shutdown(); + if (oprofile_ops.shutdown) + oprofile_ops.shutdown(); is_setup = 0; free_event_buffer(); free_cpu_buffers(); - up(&start_sem); + mutex_unlock(&start_mutex); } -extern void timer_init(struct oprofile_operations ** ops); +int oprofile_set_backtrace(unsigned long val) +{ + int err = 0; + mutex_lock(&start_mutex); -static int __init oprofile_init(void) -{ - /* Architecture must fill in the interrupt ops and the - * logical CPU type, or we can fall back to the timer - * interrupt profiler. - */ - int err = oprofile_arch_init(&oprofile_ops); + if (oprofile_started) { + err = -EBUSY; + goto out; + } - if (err == -ENODEV || timer) { - timer_init(&oprofile_ops); - err = 0; - } else if (err) { + if (!oprofile_ops.backtrace) { + err = -EINVAL; goto out; } - if (!oprofile_ops->cpu_type) { - printk(KERN_ERR "oprofile: cpu_type not set !\n"); - err = -EFAULT; - } else { - err = oprofilefs_register(); + backtrace_depth = val; + +out: + mutex_unlock(&start_mutex); + return err; +} + +static int __init oprofile_init(void) +{ + int err; + + err = oprofile_arch_init(&oprofile_ops); + + if (err < 0 || timer) { + printk(KERN_INFO "oprofile: using timer interrupt.\n"); + oprofile_timer_init(&oprofile_ops); } - + + err = oprofilefs_register(); if (err) - goto out_exit; -out: + oprofile_arch_exit(); + return err; -out_exit: - oprofile_arch_exit(); - goto out; }