s390/cpumf: Adjust registration of s390 PMU device drivers
[ Upstream commit 6a82e23f45
]
Linux-next commit titled "perf/core: Optimize perf_init_event()"
changed the semantics of PMU device driver registration.
It was done to speed up the lookup/handling of PMU device driver
specific events. It also enforces that only one PMU device
driver will be registered of type PERF_EVENT_RAW.
This change added these line in function perf_pmu_register():
...
+ ret = idr_alloc(&pmu_idr, pmu, max, 0, GFP_KERNEL);
+ if (ret < 0)
goto free_pdc;
+
+ WARN_ON(type >= 0 && ret != type);
The warn_on generates a message. We have 3 PMU device drivers,
each registered as type PERF_TYPE_RAW.
The cf_diag device driver (arch/s390/kernel/perf_cpumf_cf_diag.c)
always hits the WARN_ON because it is the second PMU device driver
(after sampling device driver arch/s390/kernel/perf_cpumf_sf.c)
which is registered as type 4 (PERF_TYPE_RAW).
So when the sampling device driver is registered, ret has value 4.
When cf_diag device driver is registered with type 4,
ret has value of 5 and WARN_ON fires.
Adjust the PMU device drivers for s390 to support the new
semantics required by perf_pmu_register().
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
5.4-rM2-2.2.x-imx-squashed
parent
44a9b673a7
commit
6549e9ccf3
|
@ -199,7 +199,7 @@ static const int cpumf_generic_events_user[] = {
|
|||
[PERF_COUNT_HW_BUS_CYCLES] = -1,
|
||||
};
|
||||
|
||||
static int __hw_perf_event_init(struct perf_event *event)
|
||||
static int __hw_perf_event_init(struct perf_event *event, unsigned int type)
|
||||
{
|
||||
struct perf_event_attr *attr = &event->attr;
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
|
@ -207,7 +207,7 @@ static int __hw_perf_event_init(struct perf_event *event)
|
|||
int err = 0;
|
||||
u64 ev;
|
||||
|
||||
switch (attr->type) {
|
||||
switch (type) {
|
||||
case PERF_TYPE_RAW:
|
||||
/* Raw events are used to access counters directly,
|
||||
* hence do not permit excludes */
|
||||
|
@ -294,17 +294,16 @@ static int __hw_perf_event_init(struct perf_event *event)
|
|||
|
||||
static int cpumf_pmu_event_init(struct perf_event *event)
|
||||
{
|
||||
unsigned int type = event->attr.type;
|
||||
int err;
|
||||
|
||||
switch (event->attr.type) {
|
||||
case PERF_TYPE_HARDWARE:
|
||||
case PERF_TYPE_HW_CACHE:
|
||||
case PERF_TYPE_RAW:
|
||||
err = __hw_perf_event_init(event);
|
||||
break;
|
||||
default:
|
||||
if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_RAW)
|
||||
err = __hw_perf_event_init(event, type);
|
||||
else if (event->pmu->type == type)
|
||||
/* Registered as unknown PMU */
|
||||
err = __hw_perf_event_init(event, PERF_TYPE_RAW);
|
||||
else
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (unlikely(err) && event->destroy)
|
||||
event->destroy(event);
|
||||
|
@ -553,7 +552,7 @@ static int __init cpumf_pmu_init(void)
|
|||
return -ENODEV;
|
||||
|
||||
cpumf_pmu.attr_groups = cpumf_cf_event_group();
|
||||
rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW);
|
||||
rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", -1);
|
||||
if (rc)
|
||||
pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc);
|
||||
return rc;
|
||||
|
|
|
@ -243,13 +243,13 @@ static int cf_diag_event_init(struct perf_event *event)
|
|||
int err = -ENOENT;
|
||||
|
||||
debug_sprintf_event(cf_diag_dbg, 5,
|
||||
"%s event %p cpu %d config %#llx "
|
||||
"%s event %p cpu %d config %#llx type:%u "
|
||||
"sample_type %#llx cf_diag_events %d\n", __func__,
|
||||
event, event->cpu, attr->config, attr->sample_type,
|
||||
atomic_read(&cf_diag_events));
|
||||
event, event->cpu, attr->config, event->pmu->type,
|
||||
attr->sample_type, atomic_read(&cf_diag_events));
|
||||
|
||||
if (event->attr.config != PERF_EVENT_CPUM_CF_DIAG ||
|
||||
event->attr.type != PERF_TYPE_RAW)
|
||||
event->attr.type != event->pmu->type)
|
||||
goto out;
|
||||
|
||||
/* Raw events are used to access counters directly,
|
||||
|
@ -693,7 +693,7 @@ static int __init cf_diag_init(void)
|
|||
}
|
||||
debug_register_view(cf_diag_dbg, &debug_sprintf_view);
|
||||
|
||||
rc = perf_pmu_register(&cf_diag, "cpum_cf_diag", PERF_TYPE_RAW);
|
||||
rc = perf_pmu_register(&cf_diag, "cpum_cf_diag", -1);
|
||||
if (rc) {
|
||||
debug_unregister_view(cf_diag_dbg, &debug_sprintf_view);
|
||||
debug_unregister(cf_diag_dbg);
|
||||
|
|
Loading…
Reference in New Issue