public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jason Baron <jbaron@redhat.com>
To: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: mingo@elte.hu, linux-kernel@vger.kernel.org, paulus@samba.org,
	rostedt@goodmis.org, fweisbec@gmail.com
Subject: [PATCH 3/2] perf_counters: add debugfs dir option
Date: Wed, 8 Jul 2009 16:17:43 -0400	[thread overview]
Message-ID: <20090708201743.GA3123@redhat.com> (raw)
In-Reply-To: <1246955360.8143.113.camel@twins>

On Tue, Jul 07, 2009 at 10:29:20AM +0200, Peter Zijlstra wrote:
> On Mon, 2009-07-06 at 17:12 -0400, Jason Baron wrote:
> > Add support to 'perf list' and 'perf stat' for kernel tracepoints. The
> > implementation creates a 'for_each_subsystem' and 'for_each_event' for
> > easy iteration over the tracepoints. The debugfs filesystem must be mounted
> > at '/sys/kernel/debug'. We can add an optional search path in the future.
> 
> I don't have a single machine that has that mount point.
> 
> 

ok, The patch below adds support for a 'PERF_DIR_DEBUGFS' environment
variable. It also adds a command line for '--debugfs-dir' and
'--debugfs-dir='. By default 'perf' continues to look in
/sys/kernel/debug, which I believe is most common.

thanks,

-Jason

Signed-off-by: Jason Baron <jbaron@redhat.com>


 tools/perf/perf.c              |   16 ++++++++
 tools/perf/util/cache.h        |    1 +
 tools/perf/util/parse-events.c |   78
++++++++++++++++++++++++----------------
 3 files changed, 62 insertions(+), 33 deletions(-)



diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index c565678..29876ee 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -122,6 +122,20 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
 			setenv(PERF_WORK_TREE_ENVIRONMENT, cmd + 12, 1);
 			if (envchanged)
 				*envchanged = 1;
+		} else if (!strcmp(cmd, "--debugfs-dir")) {
+			if (*argc < 2) {
+				fprintf(stderr, "No directory given for --debugfs-dir.\n");
+				usage(perf_usage_string);
+			}
+			setenv(PERF_DEBUGFS_ENVIRONMENT, (*argv)[1], 1);
+			if (envchanged)
+				*envchanged = 1;
+			(*argv)++;
+			(*argc)--;
+		} else if (!prefixcmp(cmd, "--debugfs-dir=")) {
+			setenv(PERF_DEBUGFS_ENVIRONMENT, cmd + 14, 1);
+			if (envchanged)
+				*envchanged = 1;
 		} else {
 			fprintf(stderr, "Unknown option: %s\n", cmd);
 			usage(perf_usage_string);
@@ -354,7 +368,7 @@ int main(int argc, const char **argv)
 	cmd = perf_extract_argv0_path(argv[0]);
 	if (!cmd)
 		cmd = "perf-help";
-
+	setenv(PERF_DEBUGFS_ENVIRONMENT, "/sys/kernel/debug/", 0);
 	/*
 	 * "perf-xxxx" is the same as "perf xxxx", but we obviously:
 	 *
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 161d5f4..4ba4b3e 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -18,6 +18,7 @@
 #define PERFATTRIBUTES_FILE ".perfattributes"
 #define INFOATTRIBUTES_FILE "info/attributes"
 #define ATTRIBUTE_MACRO_PREFIX "[attr]"
+#define PERF_DEBUGFS_ENVIRONMENT "PERF_DIR_DEBUGFS"
 
 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/parse-events.c b/tools/perf/util/parse-events.c
index d454eac..54b6c23 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -5,6 +5,7 @@
 #include "parse-events.h"
 #include "exec_cmd.h"
 #include "string.h"
+#include "cache.h"
 
 extern char *strcasestr(const char *haystack, const char *needle);
 
@@ -12,8 +13,6 @@ int					nr_counters;
 
 struct perf_counter_attr		attrs[MAX_COUNTERS];
 
-static char default_debugfs_path[] = "/sys/kernel/debug/tracing/events";
-
 struct event_symbol {
 	u8	type;
 	u64	config;
@@ -21,6 +20,8 @@ struct event_symbol {
 	char	*alias;
 };
 
+static char debugfs_path[MAXPATHLEN];
+
 #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x
 #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
 
@@ -112,30 +113,38 @@ static unsigned long hw_cache_stat[C(MAX)] = {
  [C(BPU)]	= (CACHE_READ),
 };
 
-#define for_each_subsystem(sys_dir, sys_dirent, sys_next, file, st)	       \
-	while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next)	       \
-	if (sprintf(file, "%s/%s", default_debugfs_path, sys_dirent.d_name) && \
-	   (stat(file, &st) == 0) && (S_ISDIR(st.st_mode)) &&		       \
-	   (strcmp(sys_dirent.d_name, ".") != 0) &&			       \
+#define for_each_subsystem(sys_dir, sys_dirent, sys_next, file, st)	     \
+	while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next)	     \
+	if (snprintf(file, MAXPATHLEN, "%s/%s/%s",			     \
+		     getenv(PERF_DEBUGFS_ENVIRONMENT), "tracing/events",     \
+		     sys_dirent.d_name) &&				     \
+	   (stat(file, &st) == 0) && (S_ISDIR(st.st_mode)) &&		     \
+	   (strcmp(sys_dirent.d_name, ".") != 0) &&			     \
 	   (strcmp(sys_dirent.d_name, "..") != 0))
 
-#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, file, st)    \
-	while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next)        \
-	if (sprintf(file, "%s/%s/%s", default_debugfs_path, sys_dirent.d_name, \
-			evt_dirent.d_name) && 				       \
-	   (stat(file, &st) == 0) && (S_ISDIR(st.st_mode)) &&		       \
-	   (strcmp(evt_dirent.d_name, ".") != 0) && 			       \
+#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, file, st)  \
+	while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next)	     \
+	if (snprintf(file, MAXPATHLEN, "%s/%s/%s/%s",			     \
+		     getenv(PERF_DEBUGFS_ENVIRONMENT), "tracing/events",     \
+		     sys_dirent.d_name, evt_dirent.d_name) &&		     \
+	   (stat(file, &st) == 0) && (S_ISDIR(st.st_mode)) &&		     \
+	   (strcmp(evt_dirent.d_name, ".") != 0) &&			     \
 	   (strcmp(evt_dirent.d_name, "..") != 0))
 
-#define MAX_PATH_LENGTH (strlen(default_debugfs_path) + 3 + \
-			(3 * (strlen(sys_dirent.d_name))) + 1)
 #define MAX_EVENT_LENGTH 30
 
-static int valid_debugfs_mount(void)
+static void set_debugfs_path(void)
+{
+	snprintf(debugfs_path, MAXPATHLEN, "%s/%s",
+		 getenv(PERF_DEBUGFS_ENVIRONMENT),
+		 "tracing/events");
+}
+
+static int valid_debugfs_mount(const char *mount)
 {
 	struct statfs st_fs;
 
-	if (statfs(default_debugfs_path, &st_fs) < 0)
+	if (statfs(mount, &st_fs) < 0)
 		return -ENOENT;
 	else if (st_fs.f_type != (long) DEBUGFS_MAGIC)
 		return -ENOENT;
@@ -151,12 +160,13 @@ static char *tracepoint_id_to_name(u64 config)
 	char id_buf[4];
 	int fd;
 	long long id;
-	char evt_path[MAX_PATH_LENGTH];
+	char evt_path[MAXPATHLEN];
 
-	if (valid_debugfs_mount())
+	set_debugfs_path();
+	if (valid_debugfs_mount(debugfs_path))
 		return "unkown";
 
-	sys_dir = opendir(default_debugfs_path);
+	sys_dir = opendir(debugfs_path);
 	if (!sys_dir)
 		goto cleanup;
 	for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) {
@@ -165,8 +175,9 @@ static char *tracepoint_id_to_name(u64 config)
 			goto cleanup;
 		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next,
 								evt_path, st) {
-			sprintf(evt_path, "%s/%s/%s/id", default_debugfs_path,
-				sys_dirent.d_name, evt_dirent.d_name);
+			snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id",
+				 debugfs_path, sys_dirent.d_name,
+				 evt_dirent.d_name);
 			fd = open(evt_path, O_RDONLY);
 			if (fd < 0)
 				continue;
@@ -362,9 +373,10 @@ static int parse_tracepoint_event(const char **strp,
 	int fd;
 	unsigned int sys_length, evt_length;
 	u64 id;
-	char evt_path[MAX_PATH_LENGTH];
+	char evt_path[MAXPATHLEN];
 
-	if (valid_debugfs_mount())
+	set_debugfs_path();
+	if (valid_debugfs_mount(debugfs_path))
 		return 0;
 
 	evt_name = strchr(*strp, ':');
@@ -381,7 +393,7 @@ static int parse_tracepoint_event(const char **strp,
 	} else
 		return 0;
 
-	sys_dir = opendir(default_debugfs_path);
+	sys_dir = opendir(debugfs_path);
 	if (!sys_dir)
 		goto cleanup;
 	for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) {
@@ -392,10 +404,11 @@ static int parse_tracepoint_event(const char **strp,
 			for_each_event(sys_dirent, evt_dir, evt_dirent,
 						       evt_next, evt_path, st) {
 				if (strcmp(evt_dirent.d_name, evt_name) == 0) {
-					sprintf(evt_path, "%s/%s/%s/id",
-						default_debugfs_path,
-						sys_dirent.d_name,
-						evt_dirent.d_name);
+					snprintf(evt_path, MAXPATHLEN,
+						 "%s/%s/%s/id",
+						 debugfs_path,
+						 sys_dirent.d_name,
+						 evt_dirent.d_name);
 					fd = open(evt_path, O_RDONLY);
 					if (fd < 0)
 						continue;
@@ -589,12 +602,13 @@ static void print_tracepoint_events(void)
 	DIR *sys_dir, *evt_dir;
 	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
 	struct stat st;
-	char evt_path[MAX_PATH_LENGTH];
+	char evt_path[MAXPATHLEN];
 
-	if (valid_debugfs_mount())
+	set_debugfs_path();
+	if (valid_debugfs_mount(debugfs_path))
 		return;
 
-	sys_dir = opendir(default_debugfs_path);
+	sys_dir = opendir(debugfs_path);
 	if (!sys_dir)
 		goto cleanup;
 	for_each_subsystem(sys_dir, sys_dirent, sys_next, evt_path, st) {



  reply	other threads:[~2009-07-08 20:18 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-06 21:11 [PATCH 0/2] perf_counter: add tracepoint support Jason Baron
2009-07-06 21:11 ` [PATCH 1/2] perf_counter: cleanup kernel perf counter support for tracepoints Jason Baron
2009-07-06 21:12 ` [PATCH 2/2] perf_counter: add support to the 'perf' tool " Jason Baron
2009-07-07  8:29   ` Peter Zijlstra
2009-07-08 20:17     ` Jason Baron [this message]
2009-07-09  0:47       ` [PATCH 3/2] perf_counters: add debugfs dir option Frederic Weisbecker
2009-07-09 14:45         ` Jason Baron
2009-07-10  4:17           ` Ingo Molnar
2009-07-13  7:15   ` [PATCH 2/2] perf_counter: add support to the 'perf' tool for tracepoints Ingo Molnar
2009-07-09  3:10 ` [PATCH 0/2] perf_counter: add tracepoint support Frederic Weisbecker
2009-07-09  7:58   ` Peter Zijlstra
2009-07-10  3:53     ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090708201743.GA3123@redhat.com \
    --to=jbaron@redhat.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=fweisbec@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=paulus@samba.org \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox