diff options
| -rw-r--r-- | arch/s390/oprofile/hwsampler_files.c | 60 | ||||
| -rw-r--r-- | arch/s390/oprofile/init.c | 1 | ||||
| -rw-r--r-- | drivers/oprofile/oprof.c | 32 | ||||
| -rw-r--r-- | drivers/oprofile/oprof.h | 2 | ||||
| -rw-r--r-- | drivers/oprofile/timer_int.c | 15 | ||||
| -rw-r--r-- | include/linux/oprofile.h | 21 | 
6 files changed, 41 insertions, 90 deletions
diff --git a/arch/s390/oprofile/hwsampler_files.c b/arch/s390/oprofile/hwsampler_files.c index 493f7cc4e86..2e1da2449ba 100644 --- a/arch/s390/oprofile/hwsampler_files.c +++ b/arch/s390/oprofile/hwsampler_files.c @@ -8,6 +8,7 @@  #include <linux/errno.h>  #include <linux/fs.h> +#include "../../../drivers/oprofile/oprof.h"  #include "hwsampler.h"  #define DEFAULT_INTERVAL	4096 @@ -22,12 +23,20 @@ static unsigned long oprofile_max_interval;  static unsigned long oprofile_sdbt_blocks = DEFAULT_SDBT_BLOCKS;  static unsigned long oprofile_sdb_blocks = DEFAULT_SDB_BLOCKS; -static unsigned long oprofile_hwsampler; +static int hwsampler_file; +static int hwsampler_running;	/* start_mutex must be held to change */ + +static struct oprofile_operations timer_ops;  static int oprofile_hwsampler_start(void)  {  	int retval; +	hwsampler_running = hwsampler_file; + +	if (!hwsampler_running) +		return timer_ops.start(); +  	retval = hwsampler_allocate(oprofile_sdbt_blocks, oprofile_sdb_blocks);  	if (retval)  		return retval; @@ -41,25 +50,20 @@ static int oprofile_hwsampler_start(void)  static void oprofile_hwsampler_stop(void)  { +	if (!hwsampler_running) { +		timer_ops.stop(); +		return; +	} +  	hwsampler_stop_all();  	hwsampler_deallocate();  	return;  } -int oprofile_arch_set_hwsampler(struct oprofile_operations *ops) -{ -	printk(KERN_INFO "oprofile: using hardware sampling\n"); -	ops->start = oprofile_hwsampler_start; -	ops->stop = oprofile_hwsampler_stop; -	ops->cpu_type = "timer"; - -	return 0; -} -  static ssize_t hwsampler_read(struct file *file, char __user *buf,  		size_t count, loff_t *offset)  { -	return oprofilefs_ulong_to_user(oprofile_hwsampler, buf, count, offset); +	return oprofilefs_ulong_to_user(hwsampler_file, buf, count, offset);  }  static ssize_t hwsampler_write(struct file *file, char const __user *buf, @@ -75,15 +79,16 @@ static ssize_t hwsampler_write(struct file *file, char const __user *buf,  	if (retval)  		return retval; -	if (oprofile_hwsampler == val) -		return -EINVAL; - -	retval = oprofile_set_hwsampler(val); +	if (oprofile_started) +		/* +		 * save to do without locking as we set +		 * hwsampler_running in start() when start_mutex is +		 * held +		 */ +		return -EBUSY; -	if (retval) -		return retval; +	hwsampler_file = val; -	oprofile_hwsampler = val;  	return count;  } @@ -98,7 +103,7 @@ static int oprofile_create_hwsampling_files(struct super_block *sb,  	struct dentry *hw_dir;  	/* reinitialize default values */ -	oprofile_hwsampler = 1; +	hwsampler_file = 1;  	hw_dir = oprofilefs_mkdir(sb, root, "hwsampling");  	if (!hw_dir) @@ -125,7 +130,6 @@ int oprofile_hwsampler_init(struct oprofile_operations* ops)  	/*  	 * create hwsampler files only if hwsampler_setup() succeeds.  	 */ -	ops->create_files = oprofile_create_hwsampling_files;  	oprofile_min_interval = hwsampler_query_min_interval();  	if (oprofile_min_interval < 0) {  		oprofile_min_interval = 0; @@ -136,11 +140,23 @@ int oprofile_hwsampler_init(struct oprofile_operations* ops)  		oprofile_max_interval = 0;  		return -ENODEV;  	} -	oprofile_arch_set_hwsampler(ops); + +	if (oprofile_timer_init(ops)) +		return -ENODEV; + +	printk(KERN_INFO "oprofile: using hardware sampling\n"); + +	memcpy(&timer_ops, ops, sizeof(timer_ops)); + +	ops->start = oprofile_hwsampler_start; +	ops->stop = oprofile_hwsampler_stop; +	ops->create_files = oprofile_create_hwsampling_files; +  	return 0;  }  void oprofile_hwsampler_exit(void)  { +	oprofile_timer_exit();  	hwsampler_shutdown();  } diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index f6b3f724f59..059b44b9f17 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c @@ -11,7 +11,6 @@  #include <linux/oprofile.h>  #include <linux/init.h>  #include <linux/errno.h> -#include <linux/fs.h>  extern int oprofile_hwsampler_init(struct oprofile_operations* ops);  extern void oprofile_hwsampler_exit(void); diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index 43b01daa91e..f9bda64fcd1 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c @@ -239,38 +239,6 @@ int oprofile_set_ulong(unsigned long *addr, unsigned long val)  	return err;  } -#ifdef CONFIG_HAVE_HWSAMPLER -int oprofile_set_hwsampler(unsigned long val) -{ -	int err = 0; - -	mutex_lock(&start_mutex); - -	if (oprofile_started) { -		err = -EBUSY; -		goto out; -	} - -	switch (val) { -	case 1: -		/* Switch to hardware sampling. */ -		__oprofile_timer_exit(); -		err = oprofile_arch_set_hwsampler(&oprofile_ops); -		break; -	case 0: -		printk(KERN_INFO "oprofile: using timer interrupt.\n"); -		err = __oprofile_timer_init(&oprofile_ops); -		break; -	default: -		err = -EINVAL; -	} - -out: -	mutex_unlock(&start_mutex); -	return err; -} -#endif /* CONFIG_HAVE_HWSAMPLER */ -  static int __init oprofile_init(void)  {  	int err; diff --git a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h index 5a6ceb1954a..177b73de5e5 100644 --- a/drivers/oprofile/oprof.h +++ b/drivers/oprofile/oprof.h @@ -35,9 +35,7 @@ struct dentry;  void oprofile_create_files(struct super_block *sb, struct dentry *root);  int oprofile_timer_init(struct oprofile_operations *ops); -int __oprofile_timer_init(struct oprofile_operations *ops);  void oprofile_timer_exit(void); -void __oprofile_timer_exit(void);  int oprofile_set_ulong(unsigned long *addr, unsigned long val);  int oprofile_set_timeout(unsigned long time); diff --git a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c index 0099a458fd3..3ef44624f51 100644 --- a/drivers/oprofile/timer_int.c +++ b/drivers/oprofile/timer_int.c @@ -97,13 +97,14 @@ static struct notifier_block __refdata oprofile_cpu_notifier = {  	.notifier_call = oprofile_cpu_notify,  }; -int  __oprofile_timer_init(struct oprofile_operations *ops) +int oprofile_timer_init(struct oprofile_operations *ops)  {  	int rc;  	rc = register_hotcpu_notifier(&oprofile_cpu_notifier);  	if (rc)  		return rc; +	ops->create_files = NULL;  	ops->setup = NULL;  	ops->shutdown = NULL;  	ops->start = oprofile_hrtimer_start; @@ -112,17 +113,7 @@ int  __oprofile_timer_init(struct oprofile_operations *ops)  	return 0;  } -int __init oprofile_timer_init(struct oprofile_operations *ops) -{ -	return __oprofile_timer_init(ops); -} - -void __oprofile_timer_exit(void) +void oprofile_timer_exit(void)  {  	unregister_hotcpu_notifier(&oprofile_cpu_notifier);  } - -void __exit oprofile_timer_exit(void) -{ -	__oprofile_timer_exit(); -} diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h index b517d869e1a..7f5cfd3b37d 100644 --- a/include/linux/oprofile.h +++ b/include/linux/oprofile.h @@ -91,27 +91,6 @@ int oprofile_arch_init(struct oprofile_operations * ops);   */  void oprofile_arch_exit(void); -#ifdef CONFIG_HAVE_HWSAMPLER -/** - * setup hardware sampler for oprofiling. - */ - -int oprofile_set_hwsampler(unsigned long); - -/** - * hardware sampler module initialization for the s390 arch - */ - -int oprofile_arch_set_hwsampler(struct oprofile_operations *ops); - -/** - * Add an s390 hardware sample. - */ -void oprofile_add_ext_hw_sample(unsigned long pc, struct pt_regs * const regs, -	unsigned long event, int is_kernel, -	struct task_struct *task); -#endif /* CONFIG_HAVE_HWSAMPLER */ -  /**   * Add a sample. This may be called from any context.   */  |