[PATCH 6/6 v2] perf: Make perf aware of tracefs

From: Steven Rostedt
Date: Mon Feb 02 2015 - 14:36:53 EST


From: "Steven Rostedt (Red Hat)" <rostedt@xxxxxxxxxxx>

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@xxxxxxxxxxx>
---
tools/perf/tests/open-syscall-all-cpus.c | 7 +++-
tools/perf/tests/open-syscall.c | 7 +++-
tools/perf/tests/parse-events.c | 13 +++++--
tools/perf/util/cache.h | 1 +
tools/perf/util/evlist.c | 1 -
tools/perf/util/parse-events.h | 2 +-
tools/perf/util/probe-event.c | 24 ++++++++-----
tools/perf/util/util.c | 60 ++++++++++++++++++++++++++------
tools/perf/util/util.h | 1 +
9 files changed, 91 insertions(+), 25 deletions(-)

diff --git a/tools/perf/tests/open-syscall-all-cpus.c b/tools/perf/tests/open-syscall-all-cpus.c
index 8fa82d1700c7..21969e99ea46 100644
--- a/tools/perf/tests/open-syscall-all-cpus.c
+++ b/tools/perf/tests/open-syscall-all-cpus.c
@@ -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/debug?\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;
}

diff --git a/tools/perf/tests/open-syscall.c b/tools/perf/tests/open-syscall.c
index a33b2daae40f..4250e40234d2 100644
--- a/tools/perf/tests/open-syscall.c
+++ b/tools/perf/tests/open-syscall.c
@@ -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/debug?\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;
}

diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 1cdab0ce00e2..ac243ebcb20a 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -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);

diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index d04d770d90f6..fbcca21d66ab 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -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 *);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 28b8ce86bf12..42f1a2dfead3 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -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"
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index ff6e1fa4111e..39c3b57965d1 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -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 */
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 919937eb0be2..9dfbed96bf39 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -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 */
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index b86744f29eef..92db3f156b63 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -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;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 027a5153495c..73c2f8e557ab 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -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>
--
2.1.4


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/