diff --git a/kernel/events/core.c b/kernel/events/core.c index 4d67c5d35c137ff08e771a44f802baea258a7d7b..cfd89b4a02d80d9de1f6996a00d198c14051bcd8 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -10180,7 +10180,16 @@ int perf_pmu_register(struct pmu *pmu, const char *name, int type) if (!pmu->event_idx) pmu->event_idx = perf_event_idx_default; - list_add_rcu(&pmu->entry, &pmus); + /* + * Ensure the TYPE_SOFTWARE PMUs are at the head of the list, + * since these cannot be in the IDR. This way the linear search + * is fast, provided a valid software event is provided. + */ + if (type == PERF_TYPE_SOFTWARE || !name) + list_add_rcu(&pmu->entry, &pmus); + else + list_add_tail_rcu(&pmu->entry, &pmus); + atomic_set(&pmu->exclusive_cnt, 0); ret = 0; unlock: