From: Ian Rogers Date: Sat, 27 May 2023 07:22:06 +0000 (-0700) Subject: perf pmus: Avoid repeated sysfs scanning X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=8e7d8a2eef3e48223a46e3ba676ce01a881a8519;p=linux.git perf pmus: Avoid repeated sysfs scanning perf_pmus__scan will process every directory in sysfs to see if it is a PMU, attempting to add it if not already in the pmus list. Add two booleans to record whether this scanning has been done for core or all PMUs. Skip scanning in the event that scanning has already occurred. Reviewed-by: Kan Liang Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ali Saidi Cc: Athira Rajeev Cc: Dmitrii Dolgov <9erthalion6@gmail.com> Cc: Huacai Chen Cc: Ingo Molnar Cc: James Clark Cc: Jing Zhang Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kang Minchul Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Mike Leach Cc: Ming Wang Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Rob Herring Cc: Sandipan Das Cc: Sean Christopherson Cc: Suzuki Poulouse Cc: Thomas Richter Cc: Will Deacon Cc: Xing Zhengjun Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20230527072210.2900565-31-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c index de7fc36519c99..2c512345191d0 100644 --- a/tools/perf/util/pmus.c +++ b/tools/perf/util/pmus.c @@ -14,6 +14,8 @@ static LIST_HEAD(core_pmus); static LIST_HEAD(other_pmus); +static bool read_sysfs_core_pmus; +static bool read_sysfs_all_pmus; void perf_pmus__destroy(void) { @@ -29,6 +31,8 @@ void perf_pmus__destroy(void) perf_pmu__delete(pmu); } + read_sysfs_core_pmus = false; + read_sysfs_all_pmus = false; } static struct perf_pmu *pmu_find(const char *name) @@ -53,6 +57,7 @@ struct perf_pmu *perf_pmus__find(const char *name) { struct perf_pmu *pmu; int dirfd; + bool core_pmu; /* * Once PMU is loaded it stays in the list, @@ -63,8 +68,15 @@ struct perf_pmu *perf_pmus__find(const char *name) if (pmu) return pmu; + if (read_sysfs_all_pmus) + return NULL; + + core_pmu = is_pmu_core(name); + if (core_pmu && read_sysfs_core_pmus) + return NULL; + dirfd = perf_pmu__event_source_devices_fd(); - pmu = perf_pmu__lookup(is_pmu_core(name) ? &core_pmus : &other_pmus, dirfd, name); + pmu = perf_pmu__lookup(core_pmu ? &core_pmus : &other_pmus, dirfd, name); close(dirfd); return pmu; @@ -73,6 +85,7 @@ struct perf_pmu *perf_pmus__find(const char *name) static struct perf_pmu *perf_pmu__find2(int dirfd, const char *name) { struct perf_pmu *pmu; + bool core_pmu; /* * Once PMU is loaded it stays in the list, @@ -83,7 +96,14 @@ static struct perf_pmu *perf_pmu__find2(int dirfd, const char *name) if (pmu) return pmu; - return perf_pmu__lookup(is_pmu_core(name) ? &core_pmus : &other_pmus, dirfd, name); + if (read_sysfs_all_pmus) + return NULL; + + core_pmu = is_pmu_core(name); + if (core_pmu && read_sysfs_core_pmus) + return NULL; + + return perf_pmu__lookup(core_pmu ? &core_pmus : &other_pmus, dirfd, name); } /* Add all pmus in sysfs to pmu list: */ @@ -93,6 +113,9 @@ static void pmu_read_sysfs(bool core_only) DIR *dir; struct dirent *dent; + if (read_sysfs_all_pmus || (core_only && read_sysfs_core_pmus)) + return; + fd = perf_pmu__event_source_devices_fd(); if (fd < 0) return; @@ -111,6 +134,12 @@ static void pmu_read_sysfs(bool core_only) } closedir(dir); + if (core_only) { + read_sysfs_core_pmus = true; + } else { + read_sysfs_core_pmus = true; + read_sysfs_all_pmus = true; + } } struct perf_pmu *perf_pmus__find_by_type(unsigned int type)