summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/perf_event.c
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2013-12-12 16:32:47 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-12-16 14:37:51 +0100
commit8c069ff4bd6063a3f15e606c882e03f75c7e7711 (patch)
tree39fc5d8b13aee5c4c9a8ca2e21e4fefd9a308f1a /arch/s390/kernel/perf_event.c
parents390/cpum_cf: Export event names in sysfs (diff)
downloadlinux-8c069ff4bd6063a3f15e606c882e03f75c7e7711.tar.xz
linux-8c069ff4bd6063a3f15e606c882e03f75c7e7711.zip
s390/perf: add support for the CPU-Measurement Sampling Facility
Introduce a perf PMU, "cpum_sf", to support the CPU-Measurement Sampling Facility. You can control the sampling facility through this perf PMU interfaces. Perf sampling events are created for hardware samples. For details about the CPU-Measurement Sampling Facility, see "The Load-Program-Parameter and the CPU-Measurement Facilities" (SA23-2260). Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/perf_event.c')
-rw-r--r--arch/s390/kernel/perf_event.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c
index 4c1d336ce941..b9843ba9829f 100644
--- a/arch/s390/kernel/perf_event.c
+++ b/arch/s390/kernel/perf_event.c
@@ -16,6 +16,7 @@
#include <linux/kvm_host.h>
#include <linux/percpu.h>
#include <linux/export.h>
+#include <linux/spinlock.h>
#include <linux/sysfs.h>
#include <asm/irq.h>
#include <asm/cpu_mf.h>
@@ -36,6 +37,8 @@ int perf_num_counters(void)
if (cpum_cf_avail())
num += PERF_CPUM_CF_MAX_CTR;
+ if (cpum_sf_avail())
+ num += PERF_CPUM_SF_MAX_CTR;
return num;
}
@@ -93,24 +96,45 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
: PERF_RECORD_MISC_KERNEL;
}
-void perf_event_print_debug(void)
+void print_debug_cf(void)
{
struct cpumf_ctr_info cf_info;
- unsigned long flags;
- int cpu;
-
- if (!cpum_cf_avail())
- return;
-
- local_irq_save(flags);
+ int cpu = smp_processor_id();
- cpu = smp_processor_id();
memset(&cf_info, 0, sizeof(cf_info));
if (!qctri(&cf_info))
pr_info("CPU[%i] CPUM_CF: ver=%u.%u A=%04x E=%04x C=%04x\n",
cpu, cf_info.cfvn, cf_info.csvn,
cf_info.auth_ctl, cf_info.enable_ctl, cf_info.act_ctl);
+}
+
+static void print_debug_sf(void)
+{
+ struct hws_qsi_info_block si;
+ int cpu = smp_processor_id();
+
+ memset(&si, 0, sizeof(si));
+ if (qsi(&si)) {
+ pr_err("CPU[%i]: CPM_SF: qsi failed\n");
+ return;
+ }
+
+ pr_info("CPU[%i]: CPM_SF: as=%i es=%i cs=%i bsdes=%i dsdes=%i"
+ " min=%i max=%i cpu_speed=%i tear=%p dear=%p\n",
+ cpu, si.as, si.es, si.cs, si.bsdes, si.dsdes,
+ si.min_sampl_rate, si.max_sampl_rate, si.cpu_speed,
+ si.tear, si.dear);
+}
+
+void perf_event_print_debug(void)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ if (cpum_cf_avail())
+ print_debug_cf();
+ if (cpum_sf_avail())
+ print_debug_sf();
local_irq_restore(flags);
}