perf tools: Make perf aware of tracefs
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>
Mon, 2 Feb 2015 19:35:07 +0000 (14:35 -0500)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 11 Feb 2015 15:37:08 +0000 (12:37 -0300)
As tracefs may be mounted instead of debugfs to get to the event
directories, have perf know about tracefs, and use that file system over
debugfs if it is present.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/20150202193553.340946602@goodmis.org
[ Fixed up error messages about tracefs pointed out by Namhyung ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/tests/open-syscall-all-cpus.c
tools/perf/tests/open-syscall.c
tools/perf/tests/parse-events.c
tools/perf/util/cache.h
tools/perf/util/evlist.c
tools/perf/util/parse-events.h
tools/perf/util/probe-event.c
tools/perf/util/util.c
tools/perf/util/util.h

index 8fa82d1700c725f13519ef24ca4a8fbe8b235ea3..3ec885c48f8fbcc77bdeaf0891fa54a2aa3935bc 100644 (file)
@@ -29,7 +29,12 @@ int test__open_syscall_event_on_all_cpus(void)
 
        evsel = perf_evsel__newtp("syscalls", "sys_enter_open");
        if (evsel == NULL) {
-               pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
+               if (tracefs_configured())
+                       pr_debug("is tracefs mounted on /sys/kernel/tracing?\n");
+               else if (debugfs_configured())
+                       pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
+               else
+                       pr_debug("Neither tracefs or debugfs is enabled in this kernel\n");
                goto out_thread_map_delete;
        }
 
index a33b2daae40f5239daa299a9a5335de26b39b420..07aa319bf334f37cc63d5c17efacce2faca54676 100644 (file)
@@ -18,7 +18,12 @@ int test__open_syscall_event(void)
 
        evsel = perf_evsel__newtp("syscalls", "sys_enter_open");
        if (evsel == NULL) {
-               pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
+               if (tracefs_configured())
+                       pr_debug("is tracefs mounted on /sys/kernel/tracing?\n");
+               else if (debugfs_configured())
+                       pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
+               else
+                       pr_debug("Neither tracefs or debugfs is enabled in this kernel\n");
                goto out_thread_map_delete;
        }
 
index 1cdab0ce00e2e4b291750a4dbaeef0229a599733..ac243ebcb20a224992a1ebb73ebd91afecddaf67 100644 (file)
@@ -3,6 +3,7 @@
 #include "evsel.h"
 #include "evlist.h"
 #include <api/fs/fs.h>
+#include <api/fs/tracefs.h>
 #include <api/fs/debugfs.h>
 #include "tests.h"
 #include "debug.h"
@@ -1192,11 +1193,19 @@ static int count_tracepoints(void)
 {
        char events_path[PATH_MAX];
        struct dirent *events_ent;
+       const char *mountpoint;
        DIR *events_dir;
        int cnt = 0;
 
-       scnprintf(events_path, PATH_MAX, "%s/tracing/events",
-                 debugfs_find_mountpoint());
+       mountpoint = tracefs_find_mountpoint();
+       if (mountpoint) {
+               scnprintf(events_path, PATH_MAX, "%s/events",
+                         mountpoint);
+       } else {
+               mountpoint = debugfs_find_mountpoint();
+               scnprintf(events_path, PATH_MAX, "%s/tracing/events",
+                         mountpoint);
+       }
 
        events_dir = opendir(events_path);
 
index d04d770d90f6e29bc17d4d5d1299e76278b5ee1c..fbcca21d66ab9b6887f084b19bdff98109201612 100644 (file)
@@ -17,6 +17,7 @@
 #define EXEC_PATH_ENVIRONMENT "PERF_EXEC_PATH"
 #define DEFAULT_PERF_DIR_ENVIRONMENT ".perf"
 #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
+#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
 
 typedef int (*config_fn_t)(const char *, const char *, void *);
 extern int perf_default_config(const char *, const char *, void *);
index c602ebb5b9914bec29272fd84cece63ad3b69a32..a8b2c5726abacbf3dfbf8592cdbb2a92da98774c 100644 (file)
@@ -7,7 +7,6 @@
  * Released under the GPL v2. (and only v2, not any later version)
  */
 #include "util.h"
-#include <api/fs/debugfs.h>
 #include <api/fs/fs.h>
 #include <poll.h>
 #include "cpumap.h"
index ff6e1fa4111ec7dca08c4e90da7ef14984e602cb..39c3b57965d185e8c17faee087e8620d723a5513 100644 (file)
@@ -122,6 +122,6 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
 int print_hwcache_events(const char *event_glob, bool name_only);
 extern int is_valid_tracepoint(const char *event_string);
 
-extern int valid_debugfs_mount(const char *debugfs);
+int valid_event_mount(const char *eventfs);
 
 #endif /* __PERF_PARSE_EVENTS_H */
index 919937eb0be2b643e93bfe7fc983e7131074deeb..9dfbed96bf397c81268f32c88b52e6d19c6253fb 100644 (file)
@@ -41,6 +41,7 @@
 #include "symbol.h"
 #include "thread.h"
 #include <api/fs/debugfs.h>
+#include <api/fs/tracefs.h>
 #include "trace-event.h"       /* For __maybe_unused */
 #include "probe-event.h"
 #include "probe-finder.h"
@@ -1805,7 +1806,7 @@ static void print_open_warning(int err, bool is_kprobe)
                           " - please rebuild kernel with %s.\n",
                           is_kprobe ? 'k' : 'u', config);
        } else if (err == -ENOTSUP)
-               pr_warning("Debugfs is not mounted.\n");
+               pr_warning("Tracefs or debugfs is not mounted.\n");
        else
                pr_warning("Failed to open %cprobe_events: %s\n",
                           is_kprobe ? 'k' : 'u',
@@ -1816,7 +1817,7 @@ static void print_both_open_warning(int kerr, int uerr)
 {
        /* Both kprobes and uprobes are disabled, warn it. */
        if (kerr == -ENOTSUP && uerr == -ENOTSUP)
-               pr_warning("Debugfs is not mounted.\n");
+               pr_warning("Tracefs or debugfs is not mounted.\n");
        else if (kerr == -ENOENT && uerr == -ENOENT)
                pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS "
                           "or/and CONFIG_UPROBE_EVENTS.\n");
@@ -1833,13 +1834,20 @@ static int open_probe_events(const char *trace_file, bool readwrite)
 {
        char buf[PATH_MAX];
        const char *__debugfs;
+       const char *tracing_dir = "";
        int ret;
 
-       __debugfs = debugfs_find_mountpoint();
-       if (__debugfs == NULL)
-               return -ENOTSUP;
+       __debugfs = tracefs_find_mountpoint();
+       if (__debugfs == NULL) {
+               tracing_dir = "tracing/";
 
-       ret = e_snprintf(buf, PATH_MAX, "%s/%s", __debugfs, trace_file);
+               __debugfs = debugfs_find_mountpoint();
+               if (__debugfs == NULL)
+                       return -ENOTSUP;
+       }
+
+       ret = e_snprintf(buf, PATH_MAX, "%s/%s%s",
+                        __debugfs, tracing_dir, trace_file);
        if (ret >= 0) {
                pr_debug("Opening %s write=%d\n", buf, readwrite);
                if (readwrite && !probe_event_dry_run)
@@ -1855,12 +1863,12 @@ static int open_probe_events(const char *trace_file, bool readwrite)
 
 static int open_kprobe_events(bool readwrite)
 {
-       return open_probe_events("tracing/kprobe_events", readwrite);
+       return open_probe_events("kprobe_events", readwrite);
 }
 
 static int open_uprobe_events(bool readwrite)
 {
-       return open_probe_events("tracing/uprobe_events", readwrite);
+       return open_probe_events("uprobe_events", readwrite);
 }
 
 /* Get raw string list of current kprobe_events  or uprobe_events */
index b86744f29eeffce074d2c11fd11c5330ac72bfaa..92db3f156b63d493e798620c8dbe309f0b8d3350 100644 (file)
@@ -303,13 +303,26 @@ void set_term_quiet_input(struct termios *old)
        tcsetattr(0, TCSANOW, &tc);
 }
 
-static void set_tracing_events_path(const char *mountpoint)
+static void set_tracing_events_path(const char *tracing, const char *mountpoint)
 {
-       snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s",
-                mountpoint, "tracing/events");
+       snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s",
+                mountpoint, tracing, "events");
 }
 
-const char *perf_debugfs_mount(const char *mountpoint)
+static const char *__perf_tracefs_mount(const char *mountpoint)
+{
+       const char *mnt;
+
+       mnt = tracefs_mount(mountpoint);
+       if (!mnt)
+               return NULL;
+
+       set_tracing_events_path("", mnt);
+
+       return mnt;
+}
+
+static const char *__perf_debugfs_mount(const char *mountpoint)
 {
        const char *mnt;
 
@@ -317,7 +330,20 @@ const char *perf_debugfs_mount(const char *mountpoint)
        if (!mnt)
                return NULL;
 
-       set_tracing_events_path(mnt);
+       set_tracing_events_path("tracing/", mnt);
+
+       return mnt;
+}
+
+const char *perf_debugfs_mount(const char *mountpoint)
+{
+       const char *mnt;
+
+       mnt = __perf_tracefs_mount(mountpoint);
+       if (mnt)
+               return mnt;
+
+       mnt = __perf_debugfs_mount(mountpoint);
 
        return mnt;
 }
@@ -325,12 +351,19 @@ const char *perf_debugfs_mount(const char *mountpoint)
 void perf_debugfs_set_path(const char *mntpt)
 {
        snprintf(debugfs_mountpoint, strlen(debugfs_mountpoint), "%s", mntpt);
-       set_tracing_events_path(mntpt);
+       set_tracing_events_path("tracing/", mntpt);
+}
+
+static const char *find_tracefs(void)
+{
+       const char *path = __perf_tracefs_mount(NULL);
+
+       return path;
 }
 
 static const char *find_debugfs(void)
 {
-       const char *path = perf_debugfs_mount(NULL);
+       const char *path = __perf_debugfs_mount(NULL);
 
        if (!path)
                fprintf(stderr, "Your kernel does not support the debugfs filesystem");
@@ -344,6 +377,7 @@ static const char *find_debugfs(void)
  */
 const char *find_tracing_dir(void)
 {
+       const char *tracing_dir = "";
        static char *tracing;
        static int tracing_found;
        const char *debugfs;
@@ -351,11 +385,15 @@ const char *find_tracing_dir(void)
        if (tracing_found)
                return tracing;
 
-       debugfs = find_debugfs();
-       if (!debugfs)
-               return NULL;
+       debugfs = find_tracefs();
+       if (!debugfs) {
+               tracing_dir = "/tracing";
+               debugfs = find_debugfs();
+               if (!debugfs)
+                       return NULL;
+       }
 
-       if (asprintf(&tracing, "%s/tracing", debugfs) < 0)
+       if (asprintf(&tracing, "%s%s", debugfs, tracing_dir) < 0)
                return NULL;
 
        tracing_found = 1;
index 027a5153495c8c9a087b7f624ba00d6e7f309a6f..73c2f8e557abf1becc2a8dc51336647e678114c7 100644 (file)
@@ -75,6 +75,7 @@
 #include <linux/types.h>
 #include <sys/ttydefaults.h>
 #include <api/fs/debugfs.h>
+#include <api/fs/tracefs.h>
 #include <termios.h>
 #include <linux/bitops.h>
 #include <termios.h>