From d996c726a5a4c794ed1d1e54702179d319d1c7e8 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Fri, 21 Feb 2025 22:10:12 -0800 Subject: [PATCH] perf hwmon_pmu: Switch event discovery to io_dir__readdir Avoid DIR allocations when scanning sysfs by using io_dir for the readdir implementation, that allocates about 1kb on the stack. Signed-off-by: Ian Rogers Link: https://lore.kernel.org/r/20250222061015.303622-8-irogers@google.com Signed-off-by: Namhyung Kim --- tools/perf/util/hwmon_pmu.c | 42 +++++++++++++++---------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/tools/perf/util/hwmon_pmu.c b/tools/perf/util/hwmon_pmu.c index acd889b2462f6..3cce77fc80041 100644 --- a/tools/perf/util/hwmon_pmu.c +++ b/tools/perf/util/hwmon_pmu.c @@ -11,13 +11,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include #include @@ -235,31 +235,22 @@ static void fix_name(char *p) static int hwmon_pmu__read_events(struct hwmon_pmu *pmu) { - DIR *dir; - struct dirent *ent; - int dup_fd, err = 0; + int err = 0; struct hashmap_entry *cur, *tmp; size_t bkt; + struct io_dirent64 *ent; + struct io_dir dir; if (pmu->pmu.sysfs_aliases_loaded) return 0; - /* - * Use a dup-ed fd as closedir will close it. Use openat so that the - * directory contents are refreshed. - */ - dup_fd = openat(pmu->hwmon_dir_fd, ".", O_DIRECTORY); + /* Use openat so that the directory contents are refreshed. */ + io_dir__init(&dir, openat(pmu->hwmon_dir_fd, ".", O_CLOEXEC | O_DIRECTORY | O_RDONLY)); - if (dup_fd == -1) - return -ENOMEM; + if (dir.dirfd < 0) + return -ENOENT; - dir = fdopendir(dup_fd); - if (!dir) { - close(dup_fd); - return -ENOMEM; - } - - while ((ent = readdir(dir)) != NULL) { + while ((ent = io_dir__readdir(&dir)) != NULL) { enum hwmon_type type; int number; enum hwmon_item item; @@ -347,7 +338,7 @@ static int hwmon_pmu__read_events(struct hwmon_pmu *pmu) pmu->pmu.sysfs_aliases_loaded = true; err_out: - closedir(dir); + close(dir.dirfd); return err; } @@ -702,8 +693,8 @@ int hwmon_pmu__check_alias(struct parse_events_terms *terms, struct perf_pmu_inf int perf_pmus__read_hwmon_pmus(struct list_head *pmus) { char *line = NULL; - DIR *class_hwmon_dir; - struct dirent *class_hwmon_ent; + struct io_dirent64 *class_hwmon_ent; + struct io_dir class_hwmon_dir; char buf[PATH_MAX]; const char *sysfs = sysfs__mountpoint(); @@ -711,11 +702,12 @@ int perf_pmus__read_hwmon_pmus(struct list_head *pmus) return 0; scnprintf(buf, sizeof(buf), "%s/class/hwmon/", sysfs); - class_hwmon_dir = opendir(buf); - if (!class_hwmon_dir) + io_dir__init(&class_hwmon_dir, open(buf, O_CLOEXEC | O_DIRECTORY | O_RDONLY)); + + if (class_hwmon_dir.dirfd < 0) return 0; - while ((class_hwmon_ent = readdir(class_hwmon_dir)) != NULL) { + while ((class_hwmon_ent = io_dir__readdir(&class_hwmon_dir)) != NULL) { size_t line_len; int hwmon_dir, name_fd; struct io io; @@ -745,7 +737,7 @@ int perf_pmus__read_hwmon_pmus(struct list_head *pmus) close(name_fd); } free(line); - closedir(class_hwmon_dir); + close(class_hwmon_dir.dirfd); return 0; } -- 2.50.1