diff options
author | Ian Rogers <irogers@google.com> | 2025-02-21 22:10:13 -0800 |
---|---|---|
committer | Namhyung Kim <namhyung@kernel.org> | 2025-02-24 15:46:33 -0800 |
commit | e7af1946818b302d1f8b83b6896e04e0fe8bc2eb (patch) | |
tree | 7a625235e9b7c250f3fb026aa7dd2a3cadfa1c50 | |
parent | d996c726a5a4c794ed1d1e54702179d319d1c7e8 (diff) |
perf machine: Reuse module path buffer
Rather than copying the path and appending the directory entry in a
fresh path buffer, append to the path at the end of where it is for
the recursion level. This saves a PATH_MAX buffer per recursion level
and some unnecessary copying.
Signed-off-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250222061015.303622-9-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
-rw-r--r-- | tools/perf/util/machine.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index e394c630e3a2..3f1faf94198d 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1338,22 +1338,23 @@ static int maps__set_module_path(struct maps *maps, const char *path, struct kmo return 0; } -static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, int depth) +static int maps__set_modules_path_dir(struct maps *maps, char *path, size_t path_size, int depth) { struct io_dirent64 *dent; struct io_dir iod; + size_t root_len = strlen(path); int ret = 0; - io_dir__init(&iod, open(dir_name, O_CLOEXEC | O_DIRECTORY | O_RDONLY)); + io_dir__init(&iod, open(path, O_CLOEXEC | O_DIRECTORY | O_RDONLY)); if (iod.dirfd < 0) { - pr_debug("%s: cannot open %s dir\n", __func__, dir_name); + pr_debug("%s: cannot open %s dir\n", __func__, path); return -1; } - + /* Bounds check, should never happen. */ + if (root_len >= path_size) + return -1; + path[root_len++] = '/'; while ((dent = io_dir__readdir(&iod)) != NULL) { - char path[PATH_MAX]; - - path__join(path, sizeof(path), dir_name, dent->d_name); if (io_dir__is_dir(&iod, dent)) { if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) @@ -1366,7 +1367,12 @@ static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, i continue; } - ret = maps__set_modules_path_dir(maps, path, depth + 1); + /* Bounds check, should never happen. */ + if (root_len + strlen(dent->d_name) >= path_size) + continue; + + strcpy(path + root_len, dent->d_name); + ret = maps__set_modules_path_dir(maps, path, path_size, depth + 1); if (ret < 0) goto out; } else { @@ -1376,9 +1382,14 @@ static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, i if (ret) goto out; - if (m.kmod) - ret = maps__set_module_path(maps, path, &m); + if (m.kmod) { + /* Bounds check, should never happen. */ + if (root_len + strlen(dent->d_name) < path_size) { + strcpy(path + root_len, dent->d_name); + ret = maps__set_module_path(maps, path, &m); + } + } zfree(&m.name); if (ret) @@ -1404,7 +1415,8 @@ static int machine__set_modules_path(struct machine *machine) machine->root_dir, version); free(version); - return maps__set_modules_path_dir(machine__kernel_maps(machine), modules_path, 0); + return maps__set_modules_path_dir(machine__kernel_maps(machine), + modules_path, sizeof(modules_path), 0); } int __weak arch__fix_module_text_start(u64 *start __maybe_unused, u64 *size __maybe_unused, |