diff options
author | Peter Zijlstra <peterz@infradead.org> | 2023-06-05 12:14:01 +0200 |
---|---|---|
committer | Peter Zijlstra <peterz@infradead.org> | 2023-06-06 10:09:21 +0200 |
commit | 228020b490eda9133c9cb6f59a5ee1278d8c463f (patch) | |
tree | 0d5115f8c5b8a8b58fcbd5b17dcbd7f2916b4ba0 /kernel/events | |
parent | 10d95a317ec12ec7dd4587a646c6bd6aa03c7ded (diff) | |
download | linux-228020b490eda9133c9cb6f59a5ee1278d8c463f.tar.gz linux-228020b490eda9133c9cb6f59a5ee1278d8c463f.tar.bz2 linux-228020b490eda9133c9cb6f59a5ee1278d8c463f.zip |
perf: Re-instate the linear PMU search
Full revert of commit 9551fbb64d09 ("perf/core: Remove pmu linear
searching code").
Some architectures (notably arm/arm64) still relied on the linear
search in order to find the PMU that consumes
PERF_TYPE_{HARDWARE,HW_CACHE,RAW}.
This will need a more thorought audit and cleanup.
Reported-by: Nathan Chancellor <nathan@kernel.org>
Reported-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20230605101401.GL38236@hirez.programming.kicks-ass.net
Diffstat (limited to 'kernel/events')
-rw-r--r-- | kernel/events/core.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 231b187c1a3f..c01bbe93e291 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -11630,27 +11630,38 @@ static struct pmu *perf_init_event(struct perf_event *event) } again: - ret = -ENOENT; rcu_read_lock(); pmu = idr_find(&pmu_idr, type); rcu_read_unlock(); - if (!pmu) - goto fail; + if (pmu) { + if (event->attr.type != type && type != PERF_TYPE_RAW && + !(pmu->capabilities & PERF_PMU_CAP_EXTENDED_HW_TYPE)) + goto fail; - if (event->attr.type != type && type != PERF_TYPE_RAW && - !(pmu->capabilities & PERF_PMU_CAP_EXTENDED_HW_TYPE)) - goto fail; + ret = perf_try_init_event(pmu, event); + if (ret == -ENOENT && event->attr.type != type && !extended_type) { + type = event->attr.type; + goto again; + } - ret = perf_try_init_event(pmu, event); - if (ret == -ENOENT && event->attr.type != type && !extended_type) { - type = event->attr.type; - goto again; + if (ret) + pmu = ERR_PTR(ret); + + goto unlock; } -fail: - if (ret) - pmu = ERR_PTR(ret); + list_for_each_entry_rcu(pmu, &pmus, entry, lockdep_is_held(&pmus_srcu)) { + ret = perf_try_init_event(pmu, event); + if (!ret) + goto unlock; + if (ret != -ENOENT) { + pmu = ERR_PTR(ret); + goto unlock; + } + } +fail: + pmu = ERR_PTR(-ENOENT); unlock: srcu_read_unlock(&pmus_srcu, idx); |