Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf tools: Improve startup time by reducing unnecessary stat() calls

When testing perf trace on NixOS, I noticed significant startup delays:
- `ls`: ~2ms
- `strace ls`: ~10ms
- `perf trace ls`: ~550ms

Profiling showed that 51% of the time is spent reading files,
26% in loading BPF programs, and 11% in `newfstatat`.

This patch optimizes module path exploration by avoiding `stat()` calls
unless necessary. For filesystems that do not implement `d_type`
(DT_UNKNOWN), it falls back to the old behavior.
See `readdir(3)` for details.

This reduces `perf trace ls` time to ~500ms.

A more thorough startup optimization based on command parameters would
be ideal, but that is a larger effort.

Signed-off-by: Krzysztof Łopatowski <krzysztof.m.lopatowski@gmail.com>
Acked-by: Howard Chu <howardchu95@gmail.com>
Link: https://lore.kernel.org/r/20250206113314.335376-2-krzysztof.m.lopatowski@gmail.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Krzysztof Łopatowski and committed by
Namhyung Kim
4bac7fb5 6353255e

+12 -6
+12 -6
tools/perf/util/machine.c
··· 1339 1339 1340 1340 static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, int depth) 1341 1341 { 1342 - struct dirent *dent; 1342 + const struct dirent *dent; 1343 1343 DIR *dir = opendir(dir_name); 1344 1344 int ret = 0; 1345 1345 ··· 1350 1350 1351 1351 while ((dent = readdir(dir)) != NULL) { 1352 1352 char path[PATH_MAX]; 1353 - struct stat st; 1353 + unsigned char d_type = dent->d_type; 1354 1354 1355 - /*sshfs might return bad dent->d_type, so we have to stat*/ 1356 1355 path__join(path, sizeof(path), dir_name, dent->d_name); 1357 - if (stat(path, &st)) 1358 - continue; 1359 1356 1360 - if (S_ISDIR(st.st_mode)) { 1357 + if (d_type == DT_UNKNOWN) { 1358 + struct stat st; 1359 + 1360 + if (stat(path, &st)) 1361 + continue; 1362 + if (S_ISDIR(st.st_mode)) 1363 + d_type = DT_DIR; 1364 + } 1365 + 1366 + if (d_type == DT_DIR) { 1361 1367 if (!strcmp(dent->d_name, ".") || 1362 1368 !strcmp(dent->d_name, "..")) 1363 1369 continue;