It doesn't need to traverse the filesystem hierarchy from the root. Instead it can use relative pathname with openat() and pass it to fdopendir(). Actually it can introduce some kernel lock contentions when it's invoked from multiple CPUs at the same time.
Signed-off-by: Namhyung Kim <namhy...@google.com> --- lib/pfmlib_perf_event_pmu.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/pfmlib_perf_event_pmu.c b/lib/pfmlib_perf_event_pmu.c index 718815d..4ac9299 100644 --- a/lib/pfmlib_perf_event_pmu.c +++ b/lib/pfmlib_perf_event_pmu.c @@ -356,11 +356,12 @@ gen_tracepoint_table(void) struct dirent *d1, *d2; perf_event_t *p; perf_umask_t *um; - char d2path[MAXPATHLEN]; + char POTENTIALLY_UNUSED d2path[MAXPATHLEN]; char idpath[MAXPATHLEN]; char id_str[32]; uint64_t id; int fd, err; + int POTENTIALLY_UNUSED dir1_fd; int POTENTIALLY_UNUSED dir2_fd; int reuse_event = 0; int numasks; @@ -374,7 +375,15 @@ gen_tracepoint_table(void) strncat(debugfs_mnt, "/tracing/events", MAXPATHLEN-1); debugfs_mnt[MAXPATHLEN-1]= '\0'; +#ifdef HAS_OPENAT + dir1_fd = open(debugfs_mnt, O_DIRECTORY); + if (dir1_fd < 0) + return; + + dir1 = fdopendir(dir1_fd); +#else dir1 = opendir(debugfs_mnt); +#endif if (!dir1) return; @@ -387,6 +396,17 @@ gen_tracepoint_table(void) if (!strcmp(d1->d_name, "..")) continue; +#ifdef HAS_OPENAT + /* fails if it cannot open */ + dir2_fd = openat(dir1_fd, d1->d_name, O_DIRECTORY); + if (dir2_fd < 0) + continue; + + /* fails if d2path is not a directory */ + dir2 = fdopendir(dir2_fd); + if (!dir2) + continue; +#else retlen = snprintf(d2path, MAXPATHLEN, "%s/%s", debugfs_mnt, d1->d_name); /* ensure generated d2path string is valid */ if (retlen <= 0 || MAXPATHLEN <= retlen) @@ -398,7 +418,7 @@ gen_tracepoint_table(void) continue; dir2_fd = dirfd(dir2); - +#endif /* * if a subdir did not fit our expected * tracepoint format, then we reuse the @@ -440,14 +460,14 @@ gen_tracepoint_table(void) retlen = snprintf(idpath, MAXPATHLEN, "%s/id", d2->d_name); /* ensure generated d2path string is valid */ if (retlen <= 0 || MAXPATHLEN <= retlen) - continue; + continue; fd = openat(dir2_fd, idpath, O_RDONLY); #else retlen = snprintf(idpath, MAXPATHLEN, "%s/%s/id", d2path, d2->d_name); /* ensure generated d2path string is valid */ if (retlen <= 0 || MAXPATHLEN <= retlen) - continue; + continue; fd = open(idpath, O_RDONLY); #endif -- 2.40.0.348.gf938b09366-goog _______________________________________________ perfmon2-devel mailing list perfmon2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/perfmon2-devel