summaryrefslogtreecommitdiff
path: root/drivers/oprofile
diff options
context:
space:
mode:
authorHeinz Graalfs <graalfs@linux.vnet.ibm.com>2011-01-21 10:06:53 +0000
committerRobert Richter <robert.richter@amd.com>2011-02-15 11:08:50 +0100
commit997dbb4967da248808850c250182ef2528fff2d1 (patch)
treeb41497541383c2e569b629fbab09fb2280611965 /drivers/oprofile
parentec6a3df1c008d9e8664e53b0363f6847c5c0dc3f (diff)
downloadkernel-997dbb4967da248808850c250182ef2528fff2d1.tar.gz
oprofile, s390: Enhance OProfile to support System zs hardware sampling feature
OProfile is enhanced to export all files for controlling System z's hardware sampling, and to invoke hwsampler exported functions to initialize and use System z's hardware sampling. The patch invokes hwsampler_setup() during oprofile init and exports following hwsampler files under oprofilefs if hwsampler's setup succeeded: A new directory for hardware sampling based files /dev/oprofile/hwsampling/ The userland daemon must explicitly write to the following files to disable (or enable) hardware based sampling /dev/oprofile/hwsampling/hwsampler to modify the actual sampling rate /dev/oprofile/hwsampling/hw_interval to modify the amount of sampling memory (measured in 4K pages) /dev/oprofile/hwsampling/hw_sdbt_blocks The following files are read only and show the possible minimum sampling rate /dev/oprofile/hwsampling/hw_min_interval the possible maximum sampling rate /dev/oprofile/hwsampling/hw_max_interval The patch splits the oprofile_timer_[init/exit] function so that it can be also called through user context (oprofilefs) to avoid kernel oops. Applied with following changes: * whitespace changes in Makefile and timer_int.c Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Maran Pakkirisamy <maranp@linux.vnet.ibm.com> Signed-off-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com> Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Robert Richter <robert.richter@amd.com>
Diffstat (limited to 'drivers/oprofile')
-rw-r--r--drivers/oprofile/oprof.c32
-rw-r--r--drivers/oprofile/oprof.h2
-rw-r--r--drivers/oprofile/timer_int.c15
3 files changed, 46 insertions, 3 deletions
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index f9bda64fcd1b..43b01daa91e1 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
@@ -239,6 +239,38 @@ 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 177b73de5e5f..5a6ceb1954a2 100644
--- a/drivers/oprofile/oprof.h
+++ b/drivers/oprofile/oprof.h
@@ -35,7 +35,9 @@ 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 010725117dbb..0099a458fd37 100644
--- a/drivers/oprofile/timer_int.c
+++ b/drivers/oprofile/timer_int.c
@@ -97,14 +97,13 @@ static struct notifier_block __refdata oprofile_cpu_notifier = {
.notifier_call = oprofile_cpu_notify,
};
-int __init 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;
@@ -113,7 +112,17 @@ int __init oprofile_timer_init(struct oprofile_operations *ops)
return 0;
}
-void __exit oprofile_timer_exit(void)
+int __init oprofile_timer_init(struct oprofile_operations *ops)
+{
+ return __oprofile_timer_init(ops);
+}
+
+void __oprofile_timer_exit(void)
{
unregister_hotcpu_notifier(&oprofile_cpu_notifier);
}
+
+void __exit oprofile_timer_exit(void)
+{
+ __oprofile_timer_exit();
+}