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

Reply via email to