diff options
author | Ian Rogers <irogers@google.com> | 2025-05-12 12:46:21 -0700 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2025-05-13 16:36:43 -0300 |
commit | 754baf426e099fbf3d2741e6b7fe89e2122bc00f (patch) | |
tree | b000cce41cbda528f9011035077e86e847166cd4 /tools/perf/util/hwmon_pmu.c | |
parent | 375368a9617dbf843e563d9deb6bf45751f6d770 (diff) |
perf pmu: Change aliases from list to hashmap
Finding an alias for things like perf_pmu__have_event() would need to
search the aliases list, whilst this happens relatively infrequently it
can be a significant overhead in testing.
Switch to using a hashmap. Move common initialization code to
perf_pmu__init(). Refactor the test 'struct perf_pmu_test_pmu' to not
have perf pmu within it to better support the perf_pmu__init() function.
Before:
```
$ time perf test "Parsing of PMU event table metrics"
10.3: Parsing of PMU event table metrics : Ok
10.4: Parsing of PMU event table metrics with fake PMUs : Ok
real 0m13.287s
user 0m13.026s
sys 0m0.532s
```
After:
```
$ time perf test "Parsing of PMU event table metrics"
10.3: Parsing of PMU event table metrics : Ok
10.4: Parsing of PMU event table metrics with fake PMUs : Ok
real 0m13.011s
user 0m12.885s
sys 0m0.485s
```
Committer testing:
root@number:~# grep -m1 'model name' /proc/cpuinfo
model name : AMD Ryzen 9 9950X3D 16-Core Processor
root@number:~#
Before:
root@number:~# time perf test "Parsing of PMU event table metrics"
10.3: Parsing of PMU event table metrics : Ok
10.4: Parsing of PMU event table metrics with fake PMUs : Ok
real 0m9.296s
user 0m9.361s
sys 0m0.063s
root@number:~#
After:
root@number:~# time perf test "Parsing of PMU event table metrics"
10.3: Parsing of PMU event table metrics : Ok
10.4: Parsing of PMU event table metrics with fake PMUs : Ok
real 0m9.286s
user 0m9.354s
sys 0m0.062s
root@number:~#
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Xu Yang <xu.yang_2@nxp.com>
Link: https://lore.kernel.org/r/20250512194622.33258-3-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/hwmon_pmu.c')
-rw-r--r-- | tools/perf/util/hwmon_pmu.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/tools/perf/util/hwmon_pmu.c b/tools/perf/util/hwmon_pmu.c index 3cce77fc8004..c25e7296f1c1 100644 --- a/tools/perf/util/hwmon_pmu.c +++ b/tools/perf/util/hwmon_pmu.c @@ -346,42 +346,43 @@ struct perf_pmu *hwmon_pmu__new(struct list_head *pmus, int hwmon_dir, const cha { char buf[32]; struct hwmon_pmu *hwm; + __u32 type = PERF_PMU_TYPE_HWMON_START + strtoul(sysfs_name + 5, NULL, 10); + + if (type > PERF_PMU_TYPE_HWMON_END) { + pr_err("Unable to encode hwmon type from %s in valid PMU type\n", sysfs_name); + return NULL; + } + + snprintf(buf, sizeof(buf), "hwmon_%s", name); + fix_name(buf + 6); hwm = zalloc(sizeof(*hwm)); if (!hwm) return NULL; - hwm->hwmon_dir_fd = hwmon_dir; - hwm->pmu.type = PERF_PMU_TYPE_HWMON_START + strtoul(sysfs_name + 5, NULL, 10); - if (hwm->pmu.type > PERF_PMU_TYPE_HWMON_END) { - pr_err("Unable to encode hwmon type from %s in valid PMU type\n", sysfs_name); - goto err_out; + if (perf_pmu__init(&hwm->pmu, type, buf) != 0) { + perf_pmu__delete(&hwm->pmu); + return NULL; } - snprintf(buf, sizeof(buf), "hwmon_%s", name); - fix_name(buf + 6); - hwm->pmu.name = strdup(buf); - if (!hwm->pmu.name) - goto err_out; + + hwm->hwmon_dir_fd = hwmon_dir; hwm->pmu.alias_name = strdup(sysfs_name); - if (!hwm->pmu.alias_name) - goto err_out; + if (!hwm->pmu.alias_name) { + perf_pmu__delete(&hwm->pmu); + return NULL; + } hwm->pmu.cpus = perf_cpu_map__new("0"); - if (!hwm->pmu.cpus) - goto err_out; + if (!hwm->pmu.cpus) { + perf_pmu__delete(&hwm->pmu); + return NULL; + } INIT_LIST_HEAD(&hwm->pmu.format); - INIT_LIST_HEAD(&hwm->pmu.aliases); INIT_LIST_HEAD(&hwm->pmu.caps); hashmap__init(&hwm->events, hwmon_pmu__event_hashmap_hash, hwmon_pmu__event_hashmap_equal, /*ctx=*/NULL); list_add_tail(&hwm->pmu.list, pmus); return &hwm->pmu; -err_out: - free((char *)hwm->pmu.name); - free(hwm->pmu.alias_name); - free(hwm); - close(hwmon_dir); - return NULL; } void hwmon_pmu__exit(struct perf_pmu *pmu) |