The following commit has been merged into the perf/core branch of tip: Commit-ID: 228020b490eda9133c9cb6f59a5ee1278d8c463f Gitweb: https://git.kernel.org/tip/228020b490eda9133c9cb6f59a5ee1278d8c463f Author: Peter Zijlstra <peterz@xxxxxxxxxxxxx> AuthorDate: Mon, 05 Jun 2023 12:14:01 +02:00 Committer: Peter Zijlstra <peterz@xxxxxxxxxxxxx> CommitterDate: Tue, 06 Jun 2023 10:09:21 +02:00 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@xxxxxxxxxx> Reported-by: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxx> Acked-by: Mark Rutland <mark.rutland@xxxxxxx> Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> Link: https://lkml.kernel.org/r/20230605101401.GL38236@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx --- kernel/events/core.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 231b187..c01bbe9 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);