Commit 91d5364d authored by Thomas Richter's avatar Thomas Richter Committed by Heiko Carstens

s390/cpumf: support user space events for counting

CPU Measurement counting facility events PROBLEM_STATE_CPU_CYCLES(32)
and PROBLEM_STATE_INSTRUCTIONS(33) are valid events. However the device
driver returns error -EOPNOTSUPP when these event are to be installed.

Fix this and allow installation of events PROBLEM_STATE_CPU_CYCLES,
PROBLEM_STATE_CPU_CYCLES:u, PROBLEM_STATE_INSTRUCTIONS and
PROBLEM_STATE_INSTRUCTIONS:u.
Kernel space counting only is still not supported by s390.
Signed-off-by: default avatarThomas Richter <tmricht@linux.ibm.com>
Acked-by: default avatarSumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent b7bfaa76
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/* /*
* Performance event support for s390x - CPU-measurement Counter Facility * Performance event support for s390x - CPU-measurement Counter Facility
* *
* Copyright IBM Corp. 2012, 2021 * Copyright IBM Corp. 2012, 2022
* Author(s): Hendrik Brueckner <brueckner@linux.ibm.com> * Author(s): Hendrik Brueckner <brueckner@linux.ibm.com>
* Thomas Richter <tmricht@linux.ibm.com> * Thomas Richter <tmricht@linux.ibm.com>
*/ */
...@@ -434,6 +434,12 @@ static void cpumf_hw_inuse(void) ...@@ -434,6 +434,12 @@ static void cpumf_hw_inuse(void)
mutex_unlock(&pmc_reserve_mutex); mutex_unlock(&pmc_reserve_mutex);
} }
static int is_userspace_event(u64 ev)
{
return cpumf_generic_events_user[PERF_COUNT_HW_CPU_CYCLES] == ev ||
cpumf_generic_events_user[PERF_COUNT_HW_INSTRUCTIONS] == ev;
}
static int __hw_perf_event_init(struct perf_event *event, unsigned int type) static int __hw_perf_event_init(struct perf_event *event, unsigned int type)
{ {
struct perf_event_attr *attr = &event->attr; struct perf_event_attr *attr = &event->attr;
...@@ -456,19 +462,26 @@ static int __hw_perf_event_init(struct perf_event *event, unsigned int type) ...@@ -456,19 +462,26 @@ static int __hw_perf_event_init(struct perf_event *event, unsigned int type)
if (is_sampling_event(event)) /* No sampling support */ if (is_sampling_event(event)) /* No sampling support */
return -ENOENT; return -ENOENT;
ev = attr->config; ev = attr->config;
/* Count user space (problem-state) only */
if (!attr->exclude_user && attr->exclude_kernel) { if (!attr->exclude_user && attr->exclude_kernel) {
if (ev >= ARRAY_SIZE(cpumf_generic_events_user)) /*
return -EOPNOTSUPP; * Count user space (problem-state) only
ev = cpumf_generic_events_user[ev]; * Handle events 32 and 33 as 0:u and 1:u
*/
/* No support for kernel space counters only */ if (!is_userspace_event(ev)) {
if (ev >= ARRAY_SIZE(cpumf_generic_events_user))
return -EOPNOTSUPP;
ev = cpumf_generic_events_user[ev];
}
} else if (!attr->exclude_kernel && attr->exclude_user) { } else if (!attr->exclude_kernel && attr->exclude_user) {
/* No support for kernel space counters only */
return -EOPNOTSUPP; return -EOPNOTSUPP;
} else { /* Count user and kernel space */ } else {
if (ev >= ARRAY_SIZE(cpumf_generic_events_basic)) /* Count user and kernel space, incl. events 32 + 33 */
return -EOPNOTSUPP; if (!is_userspace_event(ev)) {
ev = cpumf_generic_events_basic[ev]; if (ev >= ARRAY_SIZE(cpumf_generic_events_basic))
return -EOPNOTSUPP;
ev = cpumf_generic_events_basic[ev];
}
} }
break; break;
......
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