Skip to content

Commit 99c64b6

Browse files
hbruecknerMartin Schwidefsky
authored andcommitted
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: Hendrik Brueckner <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent e28bb79 commit 99c64b6

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

arch/s390/kernel/perf_event.c

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,19 @@
1616
#include <linux/kvm_host.h>
1717
#include <linux/percpu.h>
1818
#include <linux/export.h>
19+
#include <linux/seq_file.h>
1920
#include <linux/spinlock.h>
2021
#include <linux/sysfs.h>
2122
#include <asm/irq.h>
2223
#include <asm/cpu_mf.h>
2324
#include <asm/lowcore.h>
2425
#include <asm/processor.h>
26+
#include <asm/sysinfo.h>
2527

2628
const char *perf_pmu_name(void)
2729
{
2830
if (cpum_cf_avail() || cpum_sf_avail())
29-
return "CPU-measurement facilities (CPUMF)";
31+
return "CPU-Measurement Facilities (CPU-MF)";
3032
return "pmu";
3133
}
3234
EXPORT_SYMBOL(perf_pmu_name);
@@ -138,6 +140,60 @@ void perf_event_print_debug(void)
138140
local_irq_restore(flags);
139141
}
140142

143+
/* Service level infrastructure */
144+
static void sl_print_counter(struct seq_file *m)
145+
{
146+
struct cpumf_ctr_info ci;
147+
148+
memset(&ci, 0, sizeof(ci));
149+
if (qctri(&ci))
150+
return;
151+
152+
seq_printf(m, "CPU-MF: Counter facility: version=%u.%u "
153+
"authorization=%04x\n", ci.cfvn, ci.csvn, ci.auth_ctl);
154+
}
155+
156+
static void sl_print_sampling(struct seq_file *m)
157+
{
158+
struct hws_qsi_info_block si;
159+
160+
memset(&si, 0, sizeof(si));
161+
if (qsi(&si))
162+
return;
163+
164+
if (!si.as && !si.ad)
165+
return;
166+
167+
seq_printf(m, "CPU-MF: Sampling facility: min_rate=%lu max_rate=%lu"
168+
" cpu_speed=%u\n", si.min_sampl_rate, si.max_sampl_rate,
169+
si.cpu_speed);
170+
if (si.as)
171+
seq_printf(m, "CPU-MF: Sampling facility: mode=basic"
172+
" sample_size=%u\n", si.bsdes);
173+
if (si.ad)
174+
seq_printf(m, "CPU-MF: Sampling facility: mode=diagnostic"
175+
" sample_size=%u\n", si.dsdes);
176+
}
177+
178+
static void service_level_perf_print(struct seq_file *m,
179+
struct service_level *sl)
180+
{
181+
if (cpum_cf_avail())
182+
sl_print_counter(m);
183+
if (cpum_sf_avail())
184+
sl_print_sampling(m);
185+
}
186+
187+
static struct service_level service_level_perf = {
188+
.seq_print = service_level_perf_print,
189+
};
190+
191+
static int __init service_level_perf_register(void)
192+
{
193+
return register_service_level(&service_level_perf);
194+
}
195+
arch_initcall(service_level_perf_register);
196+
141197
/* See also arch/s390/kernel/traps.c */
142198
static unsigned long __store_trace(struct perf_callchain_entry *entry,
143199
unsigned long sp,

0 commit comments

Comments
 (0)