s390/perf: Add service level information for CPU-Measurement Facilities
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Fri, 13 Dec 2013 11:38:39 +0000 (12:38 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 16 Dec 2013 13:37:53 +0000 (14:37 +0100)
Register a service level handler to report information about available
CPU-Measurement facilities.

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/kernel/perf_event.c

index 4edcdfa4894e333c4a674b9fcf29cea3f5419682..3bd2bf030ad444a39b1c99afed90b4b2ba2c3ef1 100644 (file)
 #include <linux/kvm_host.h>
 #include <linux/percpu.h>
 #include <linux/export.h>
+#include <linux/seq_file.h>
 #include <linux/spinlock.h>
 #include <linux/sysfs.h>
 #include <asm/irq.h>
 #include <asm/cpu_mf.h>
 #include <asm/lowcore.h>
 #include <asm/processor.h>
+#include <asm/sysinfo.h>
 
 const char *perf_pmu_name(void)
 {
        if (cpum_cf_avail() || cpum_sf_avail())
-               return "CPU-measurement facilities (CPUMF)";
+               return "CPU-Measurement Facilities (CPU-MF)";
        return "pmu";
 }
 EXPORT_SYMBOL(perf_pmu_name);
@@ -138,6 +140,60 @@ void perf_event_print_debug(void)
        local_irq_restore(flags);
 }
 
+/* Service level infrastructure */
+static void sl_print_counter(struct seq_file *m)
+{
+       struct cpumf_ctr_info ci;
+
+       memset(&ci, 0, sizeof(ci));
+       if (qctri(&ci))
+               return;
+
+       seq_printf(m, "CPU-MF: Counter facility: version=%u.%u "
+                  "authorization=%04x\n", ci.cfvn, ci.csvn, ci.auth_ctl);
+}
+
+static void sl_print_sampling(struct seq_file *m)
+{
+       struct hws_qsi_info_block si;
+
+       memset(&si, 0, sizeof(si));
+       if (qsi(&si))
+               return;
+
+       if (!si.as && !si.ad)
+               return;
+
+       seq_printf(m, "CPU-MF: Sampling facility: min_rate=%lu max_rate=%lu"
+                  " cpu_speed=%u\n", si.min_sampl_rate, si.max_sampl_rate,
+                  si.cpu_speed);
+       if (si.as)
+               seq_printf(m, "CPU-MF: Sampling facility: mode=basic"
+                          " sample_size=%u\n", si.bsdes);
+       if (si.ad)
+               seq_printf(m, "CPU-MF: Sampling facility: mode=diagnostic"
+                          " sample_size=%u\n", si.dsdes);
+}
+
+static void service_level_perf_print(struct seq_file *m,
+                                    struct service_level *sl)
+{
+       if (cpum_cf_avail())
+               sl_print_counter(m);
+       if (cpum_sf_avail())
+               sl_print_sampling(m);
+}
+
+static struct service_level service_level_perf = {
+       .seq_print = service_level_perf_print,
+};
+
+static int __init service_level_perf_register(void)
+{
+       return register_service_level(&service_level_perf);
+}
+arch_initcall(service_level_perf_register);
+
 /* See also arch/s390/kernel/traps.c */
 static unsigned long __store_trace(struct perf_callchain_entry *entry,
                                   unsigned long sp,