Commit 99c64b66 authored by Hendrik Brueckner's avatar Hendrik Brueckner Committed by Martin Schwidefsky

s390/perf: Add service level information for CPU-Measurement Facilities

Register a service level handler to report information about available
CPU-Measurement facilities.
Signed-off-by: default avatarHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent e28bb79d
...@@ -16,17 +16,19 @@ ...@@ -16,17 +16,19 @@
#include <linux/kvm_host.h> #include <linux/kvm_host.h>
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/cpu_mf.h> #include <asm/cpu_mf.h>
#include <asm/lowcore.h> #include <asm/lowcore.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/sysinfo.h>
const char *perf_pmu_name(void) const char *perf_pmu_name(void)
{ {
if (cpum_cf_avail() || cpum_sf_avail()) if (cpum_cf_avail() || cpum_sf_avail())
return "CPU-measurement facilities (CPUMF)"; return "CPU-Measurement Facilities (CPU-MF)";
return "pmu"; return "pmu";
} }
EXPORT_SYMBOL(perf_pmu_name); EXPORT_SYMBOL(perf_pmu_name);
...@@ -138,6 +140,60 @@ void perf_event_print_debug(void) ...@@ -138,6 +140,60 @@ void perf_event_print_debug(void)
local_irq_restore(flags); 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 */ /* See also arch/s390/kernel/traps.c */
static unsigned long __store_trace(struct perf_callchain_entry *entry, static unsigned long __store_trace(struct perf_callchain_entry *entry,
unsigned long sp, unsigned long sp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment