perf pmu: Parse pmu caps sysfs only once
authorRavi Bangoria <ravi.bangoria@amd.com>
Sat, 4 Jun 2022 04:45:13 +0000 (10:15 +0530)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 24 Jun 2022 16:18:55 +0000 (13:18 -0300)
In addition to returning nr_caps, cache it locally in struct perf_pmu.

Similarly, cache status of whether caps sysfs has already been parsed
or not. These will help to avoid parsing sysfs every time the function
gets called.

Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Ananth Narayan <ananth.narayan@amd.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kim Phillips <kim.phillips@amd.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <rrichter@amd.com>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Santosh Shukla <santosh.shukla@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: like.xu.linux@gmail.com
Cc: x86@kernel.org
Link: https://lore.kernel.org/r/20220604044519.594-3-ravi.bangoria@amd.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/pmu.c
tools/perf/util/pmu.h

index 9a1c7e63e6630f6d253789868c03deb96a29d01f..0112e1c364185aec2abbf53c5140f18b7307a2f4 100644 (file)
@@ -1890,7 +1890,11 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu)
        const char *sysfs = sysfs__mountpoint();
        DIR *caps_dir;
        struct dirent *evt_ent;
-       int nr_caps = 0;
+
+       if (pmu->caps_initialized)
+               return pmu->nr_caps;
+
+       pmu->nr_caps = 0;
 
        if (!sysfs)
                return -1;
@@ -1898,8 +1902,10 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu)
        snprintf(caps_path, PATH_MAX,
                 "%s" EVENT_SOURCE_DEVICE_PATH "%s/caps", sysfs, pmu->name);
 
-       if (stat(caps_path, &st) < 0)
+       if (stat(caps_path, &st) < 0) {
+               pmu->caps_initialized = true;
                return 0;       /* no error if caps does not exist */
+       }
 
        caps_dir = opendir(caps_path);
        if (!caps_dir)
@@ -1926,13 +1932,14 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu)
                        continue;
                }
 
-               nr_caps++;
+               pmu->nr_caps++;
                fclose(file);
        }
 
        closedir(caps_dir);
 
-       return nr_caps;
+       pmu->caps_initialized = true;
+       return pmu->nr_caps;
 }
 
 void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
index 541889fa9f9c6cf6fb3d3b9920bc731a90cf0546..4b45fd8da5a325adaf5097299689d5df561df2fa 100644 (file)
@@ -46,6 +46,8 @@ struct perf_pmu {
        struct perf_cpu_map *cpus;
        struct list_head format;  /* HEAD struct perf_pmu_format -> list */
        struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */
+       bool caps_initialized;
+       u32 nr_caps;
        struct list_head caps;    /* HEAD struct perf_pmu_caps -> list */
        struct list_head list;    /* ELEM */
        struct list_head hybrid_list;