linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] perf trace enhancements
@ 2013-09-28 19:12 David Ahern
  2013-09-28 19:12 ` [PATCH 1/7] perf util: Add machine method to loop over threads and invoke handler David Ahern
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: David Ahern @ 2013-09-28 19:12 UTC (permalink / raw)
  To: acme, linux-kernel; +Cc: David Ahern

Hi Arnaldo:

Some more enhancements to perf-trace. It is based on your perf/trace
branch to keep the conflicts down based on the work you are doing.

David Ahern (7):
  perf util: Add machine method to loop over threads and invoke handler
  perf trace: Use new machine method to loop over threads
  perf trace: Fix comm resolution when reading events from file
  perf trace: Add record option
  perf util: Add priv variable to intlist
  perf util: Add findnew method to intlist
  perf trace: Add summary option to dump syscall statistics

 tools/perf/Documentation/perf-trace.txt |   16 ++-
 tools/perf/builtin-trace.c              |  237 +++++++++++++++++++++++++------
 tools/perf/util/intlist.c               |   11 ++
 tools/perf/util/intlist.h               |    2 +
 tools/perf/util/machine.c               |   23 +++
 tools/perf/util/machine.h               |    4 +
 6 files changed, 246 insertions(+), 47 deletions(-)

-- 
1.7.10.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/7] perf util: Add machine method to loop over threads and invoke handler
  2013-09-28 19:12 [PATCH 0/7] perf trace enhancements David Ahern
@ 2013-09-28 19:12 ` David Ahern
  2013-10-15  5:30   ` [tip:perf/core] perf machine: Add " tip-bot for David Ahern
  2013-09-28 19:12 ` [PATCH 2/7] perf trace: Use new machine method to loop over threads David Ahern
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: David Ahern @ 2013-09-28 19:12 UTC (permalink / raw)
  To: acme, linux-kernel
  Cc: David Ahern, Arnaldo Carvalho de Melo, Ingo Molnar,
	Frederic Weisbecker, Peter Zijlstra, Jiri Olsa, Namhyung Kim,
	Stephane Eranian

Loop over all threads within a machine - including threads moved to the
dead threads list -- and invoked a function. This allows commands to run
some specific function on each thread (eg., dump statistics) yet hides
how the threads are maintained within the machine and

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Stephane Eranian <eranian@google.com>
---
 tools/perf/util/machine.c |   23 +++++++++++++++++++++++
 tools/perf/util/machine.h |    4 ++++
 2 files changed, 27 insertions(+)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 40083df..d5055be 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1376,3 +1376,26 @@ int machine__resolve_callchain(struct machine *machine,
 				   sample);
 
 }
+
+int machine__for_each_thread(struct machine *machine,
+			     int (*fn)(struct thread *thread, void *p),
+			     void *priv)
+{
+	struct rb_node *nd;
+	struct thread *thread;
+	int rc = 0;
+
+	for (nd = rb_first(&machine->threads); nd; nd = rb_next(nd)) {
+		thread = rb_entry(nd, struct thread, rb_node);
+		rc = fn(thread, priv);
+		if (rc != 0)
+			return rc;
+	}
+
+	list_for_each_entry(thread, &machine->dead_threads, node) {
+		rc = fn(thread, priv);
+		if (rc != 0)
+			return rc;
+	}
+	return rc;
+}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 58a6be1..dc9c57e 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -165,4 +165,8 @@ void machines__destroy_kernel_maps(struct machines *machines);
 
 size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);
 
+int machine__for_each_thread(struct machine *machine,
+			     int (*fn)(struct thread *thread, void *p),
+			     void *priv);
+
 #endif /* __PERF_MACHINE_H */
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/7] perf trace: Use new machine method to loop over threads
  2013-09-28 19:12 [PATCH 0/7] perf trace enhancements David Ahern
  2013-09-28 19:12 ` [PATCH 1/7] perf util: Add machine method to loop over threads and invoke handler David Ahern
@ 2013-09-28 19:12 ` David Ahern
  2013-10-15  5:30   ` [tip:perf/core] " tip-bot for David Ahern
  2013-09-28 19:13 ` [PATCH 3/7] perf trace: Fix comm resolution when reading events from file David Ahern
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: David Ahern @ 2013-09-28 19:12 UTC (permalink / raw)
  To: acme, linux-kernel
  Cc: David Ahern, Arnaldo Carvalho de Melo, Ingo Molnar,
	Frederic Weisbecker, Peter Zijlstra, Jiri Olsa, Namhyung Kim,
	Stephane Eranian

Use the new machine method that loops over threads to dump summary
data.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Stephane Eranian <eranian@google.com>
---
 tools/perf/builtin-trace.c |   76 ++++++++++++++++++++++++++++----------------
 1 file changed, 48 insertions(+), 28 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 7290b69..0c93928 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1764,37 +1764,57 @@ static size_t trace__fprintf_threads_header(FILE *fp)
 	return printed;
 }
 
+/* struct used to pass data to per-thread function */
+struct summary_data {
+	FILE *fp;
+	struct trace *trace;
+	size_t printed;
+};
+
+static int trace__fprintf_one_thread(struct thread *thread, void *priv)
+{
+	struct summary_data *data = priv;
+	FILE *fp = data->fp;
+	size_t printed = data->printed;
+	struct trace *trace = data->trace;
+	struct thread_trace *ttrace = thread->priv;
+	const char *color;
+	double ratio;
+
+	if (ttrace == NULL)
+		return 0;
+
+	ratio = (double)ttrace->nr_events / trace->nr_events * 100.0;
+
+	color = PERF_COLOR_NORMAL;
+	if (ratio > 50.0)
+		color = PERF_COLOR_RED;
+	else if (ratio > 25.0)
+		color = PERF_COLOR_GREEN;
+	else if (ratio > 5.0)
+		color = PERF_COLOR_YELLOW;
+
+	printed += color_fprintf(fp, color, "%20s", thread->comm);
+	printed += fprintf(fp, " - %-5d :%11lu   [", thread->tid, ttrace->nr_events);
+	printed += color_fprintf(fp, color, "%5.1f%%", ratio);
+	printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
+
+	data->printed += printed;
+
+	return 0;
+}
+
 static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
 {
-	size_t printed = trace__fprintf_threads_header(fp);
-	struct rb_node *nd;
-
-	for (nd = rb_first(&trace->host.threads); nd; nd = rb_next(nd)) {
-		struct thread *thread = rb_entry(nd, struct thread, rb_node);
-		struct thread_trace *ttrace = thread->priv;
-		const char *color;
-		double ratio;
-
-		if (ttrace == NULL)
-			continue;
-
-		ratio = (double)ttrace->nr_events / trace->nr_events * 100.0;
-
-		color = PERF_COLOR_NORMAL;
-		if (ratio > 50.0)
-			color = PERF_COLOR_RED;
-		else if (ratio > 25.0)
-			color = PERF_COLOR_GREEN;
-		else if (ratio > 5.0)
-			color = PERF_COLOR_YELLOW;
-
-		printed += color_fprintf(fp, color, "%20s", thread->comm);
-		printed += fprintf(fp, " - %-5d :%11lu   [", thread->tid, ttrace->nr_events);
-		printed += color_fprintf(fp, color, "%5.1f%%", ratio);
-		printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
-	}
+	struct summary_data data = {
+		.fp = fp,
+		.trace = trace
+	};
+	data.printed = trace__fprintf_threads_header(fp);
 
-	return printed;
+	machine__for_each_thread(&trace->host, trace__fprintf_one_thread, &data);
+
+	return data.printed;
 }
 
 static int trace__set_duration(const struct option *opt, const char *str,
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/7] perf trace: Fix comm resolution when reading events from file
  2013-09-28 19:12 [PATCH 0/7] perf trace enhancements David Ahern
  2013-09-28 19:12 ` [PATCH 1/7] perf util: Add machine method to loop over threads and invoke handler David Ahern
  2013-09-28 19:12 ` [PATCH 2/7] perf trace: Use new machine method to loop over threads David Ahern
@ 2013-09-28 19:13 ` David Ahern
  2013-10-15  5:30   ` [tip:perf/core] " tip-bot for David Ahern
  2013-09-28 19:13 ` [PATCH 4/7] perf trace: Add record option David Ahern
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: David Ahern @ 2013-09-28 19:13 UTC (permalink / raw)
  To: acme, linux-kernel
  Cc: David Ahern, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra,
	Jiri Olsa, Namhyung Kim, Stephane Eranian

Task comm's are getting lost when processing events from a file. The problem is
that the trace struct used by the live processing has its host machine and the
perf-session used for file based processing has its host machine.  Fix by
having both references point to the same machine.

Before:

     0.030 ( 0.001 ms): :27743/27743 brk( ...
     0.057 ( 0.004 ms): :27743/27743 mmap(len: 4096, prot: READ|WRITE, flags: ...
     0.075 ( 0.006 ms): :27743/27743 access(filename: 0x7f3809fbce00, mode: R ...
     0.091 ( 0.005 ms): :27743/27743 open(filename: 0x7f3809fba14c, flags: CLOEXEC ...
...

After:
     0.030 ( 0.001 ms): make/27743 brk( ...
     0.057 ( 0.004 ms): make/27743 mmap(len: 4096, prot: READ|WRITE, flags: ...
     0.075 ( 0.006 ms): make/27743 access(filename: 0x7f3809fbce00, mode: R ...
     0.091 ( 0.005 ms): make/27743 open(filename: 0x7f3809fba14c, flags: CLOEXEC ...
...

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Stephane Eranian <eranian@google.com>
---
 tools/perf/builtin-trace.c |   29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 0c93928..420e48b 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -892,7 +892,7 @@ struct trace {
 		struct syscall  *table;
 	} syscalls;
 	struct perf_record_opts opts;
-	struct machine		host;
+	struct machine		*host;
 	u64			base_time;
 	bool			full_time;
 	FILE			*output;
@@ -1079,26 +1079,33 @@ static int trace__tool_process(struct perf_tool *tool,
 
 static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
 {
+	struct machine *host;
 	int err = symbol__init();
 
 	if (err)
 		return err;
 
-	machine__init(&trace->host, "", HOST_KERNEL_ID);
-	machine__create_kernel_maps(&trace->host);
+	host = malloc(sizeof(*host));
+	if (host == NULL)
+		return -ENOMEM;
+
+	machine__init(host, "", HOST_KERNEL_ID);
+	machine__create_kernel_maps(host);
 
 	if (perf_target__has_task(&trace->opts.target)) {
 		err = perf_event__synthesize_thread_map(&trace->tool, evlist->threads,
 							trace__tool_process,
-							&trace->host);
+							host);
 	} else {
 		err = perf_event__synthesize_threads(&trace->tool, trace__tool_process,
-						     &trace->host);
+						     host);
 	}
 
 	if (err)
 		symbol__exit();
 
+	trace->host = host;
+
 	return err;
 }
 
@@ -1303,7 +1310,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
 	if (sc->filtered)
 		return 0;
 
-	thread = machine__findnew_thread(&trace->host, sample->pid,
+	thread = machine__findnew_thread(trace->host, sample->pid,
 					 sample->tid);
 	ttrace = thread__trace(thread, trace->output);
 	if (ttrace == NULL)
@@ -1357,7 +1364,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
 	if (sc->filtered)
 		return 0;
 
-	thread = machine__findnew_thread(&trace->host, sample->pid,
+	thread = machine__findnew_thread(trace->host, sample->pid,
 					 sample->tid);
 	ttrace = thread__trace(thread, trace->output);
 	if (ttrace == NULL)
@@ -1427,7 +1434,7 @@ static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evs
 {
         u64 runtime = perf_evsel__intval(evsel, sample, "runtime");
 	double runtime_ms = (double)runtime / NSEC_PER_MSEC;
-	struct thread *thread = machine__findnew_thread(&trace->host,
+	struct thread *thread = machine__findnew_thread(trace->host,
 							sample->pid,
 							sample->tid);
 	struct thread_trace *ttrace = thread__trace(thread, trace->output);
@@ -1628,7 +1635,7 @@ again:
 				trace->base_time = sample.time;
 
 			if (type != PERF_RECORD_SAMPLE) {
-				trace__process_event(trace, &trace->host, event);
+				trace__process_event(trace, trace->host, event);
 				continue;
 			}
 
@@ -1722,6 +1729,8 @@ static int trace__replay(struct trace *trace)
 	if (session == NULL)
 		return -ENOMEM;
 
+	trace->host = &session->machines.host;
+
 	err = perf_session__set_tracepoints_handlers(session, handlers);
 	if (err)
 		goto out;
@@ -1812,7 +1821,7 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
 	};
 	data.printed = trace__fprintf_threads_header(fp);
 
-	machine__for_each_thread(&trace->host, trace__fprintf_one_thread, &data);
+	machine__for_each_thread(trace->host, trace__fprintf_one_thread, &data);
 
 	return data.printed;
 }
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 4/7] perf trace: Add record option
  2013-09-28 19:12 [PATCH 0/7] perf trace enhancements David Ahern
                   ` (2 preceding siblings ...)
  2013-09-28 19:13 ` [PATCH 3/7] perf trace: Fix comm resolution when reading events from file David Ahern
@ 2013-09-28 19:13 ` David Ahern
  2013-10-15  5:30   ` [tip:perf/core] " tip-bot for David Ahern
  2013-09-28 19:13 ` [PATCH 5/7] perf util: Add priv variable to intlist David Ahern
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: David Ahern @ 2013-09-28 19:13 UTC (permalink / raw)
  To: acme, linux-kernel
  Cc: David Ahern, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra,
	Jiri Olsa, Namhyung Kim, Stephane Eranian

record option is a convience alias to include the -e raw_syscalls:*
argument to perf-record. All other options are passed to perf-record's
handler. Resulting data file can be analyzed by perf-trace -i.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Stephane Eranian <eranian@google.com>
---
 tools/perf/Documentation/perf-trace.txt |   12 +++++++++---
 tools/perf/builtin-trace.c              |   32 +++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index b927e6f..6728b00 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -9,6 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'perf trace'
+'perf trace record'
 
 DESCRIPTION
 -----------
@@ -16,9 +17,14 @@ This command will show the events associated with the target, initially
 syscalls, but other system events like pagefaults, task lifetime events,
 scheduling events, etc.
 
-Initially this is a live mode only tool, but eventually will work with
-perf.data files like the other tools, allowing a detached 'record' from
-analysis phases.
+This is a live mode tool in addition to working with perf.data files like
+the other perf tools. Files can be generated using the 'perf record' command
+but the session needs to include the raw_syscalls events (-e 'raw_syscalls:*').
+Alernatively, the 'perf trace record' can be used as a shortcut to
+automatically include the raw_syscalls events when writing events to a file.
+
+The following options apply to perf trace; options to perf trace record are
+found in the perf record man page.
 
 OPTIONS
 -------
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 420e48b..ab42148 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1538,6 +1538,33 @@ static void perf_evlist__add_vfs_getname(struct perf_evlist *evlist)
 	perf_evlist__add(evlist, evsel);
 }
 
+static int trace__record(int argc, const char **argv)
+{
+	unsigned int rec_argc, i, j;
+	const char **rec_argv;
+	const char * const record_args[] = {
+		"record",
+		"-R",
+		"-m", "1024",
+		"-c", "1",
+		"-e", "raw_syscalls:sys_enter,raw_syscalls:sys_exit",
+	};
+
+	rec_argc = ARRAY_SIZE(record_args) + argc;
+	rec_argv = calloc(rec_argc + 1, sizeof(char *));
+
+	if (rec_argv == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(record_args); i++)
+		rec_argv[i] = record_args[i];
+
+	for (j = 0; j < (unsigned int)argc; j++, i++)
+		rec_argv[i] = argv[j];
+
+	return cmd_record(i, rec_argv, NULL);
+}
+
 static int trace__run(struct trace *trace, int argc, const char **argv)
 {
 	struct perf_evlist *evlist = perf_evlist__new();
@@ -1857,6 +1884,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 	const char * const trace_usage[] = {
 		"perf trace [<options>] [<command>]",
 		"perf trace [<options>] -- <command> [<options>]",
+		"perf trace record [<options>] [<command>]",
+		"perf trace record [<options>] -- <command> [<options>]",
 		NULL
 	};
 	struct trace trace = {
@@ -1917,6 +1946,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 	int err;
 	char bf[BUFSIZ];
 
+	if ((argc > 1) && (strcmp(argv[1], "record") == 0))
+		return trace__record(argc-2, &argv[2]);
+
 	argc = parse_options(argc, argv, trace_options, trace_usage, 0);
 
 	if (output_name != NULL) {
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 5/7] perf util: Add priv variable to intlist
  2013-09-28 19:12 [PATCH 0/7] perf trace enhancements David Ahern
                   ` (3 preceding siblings ...)
  2013-09-28 19:13 ` [PATCH 4/7] perf trace: Add record option David Ahern
@ 2013-09-28 19:13 ` David Ahern
  2013-10-15  5:31   ` [tip:perf/core] perf intlist: Add priv member tip-bot for David Ahern
  2013-09-28 19:13 ` [PATCH 6/7] perf util: Add findnew method to intlist David Ahern
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: David Ahern @ 2013-09-28 19:13 UTC (permalink / raw)
  To: acme, linux-kernel
  Cc: David Ahern, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra,
	Jiri Olsa, Namhyung Kim, Stephane Eranian

Allows commands to leverage intlist infrastructure for opaque
structures. For example an upcoming perf-trace change will use
this as a means of tracking syscalls statistics by task.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Stephane Eranian <eranian@google.com>
---
 tools/perf/util/intlist.c |    1 +
 tools/perf/util/intlist.h |    1 +
 2 files changed, 2 insertions(+)

diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c
index 11a8d86..826d7b3 100644
--- a/tools/perf/util/intlist.c
+++ b/tools/perf/util/intlist.c
@@ -20,6 +20,7 @@ static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
 
 	if (node != NULL) {
 		node->i = i;
+		node->priv = NULL;
 		rc = &node->rb_node;
 	}
 
diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h
index 62351da..0eb00ac 100644
--- a/tools/perf/util/intlist.h
+++ b/tools/perf/util/intlist.h
@@ -9,6 +9,7 @@
 struct int_node {
 	struct rb_node rb_node;
 	int i;
+	void *priv;
 };
 
 struct intlist {
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 6/7] perf util: Add findnew method to intlist
  2013-09-28 19:12 [PATCH 0/7] perf trace enhancements David Ahern
                   ` (4 preceding siblings ...)
  2013-09-28 19:13 ` [PATCH 5/7] perf util: Add priv variable to intlist David Ahern
@ 2013-09-28 19:13 ` David Ahern
  2013-10-08 13:22   ` Arnaldo Carvalho de Melo
  2013-09-28 19:13 ` [PATCH 7/7] perf trace: Add summary option to dump syscall statistics David Ahern
  2013-10-08  1:44 ` [PATCH 0/7] perf trace enhancements David Ahern
  7 siblings, 1 reply; 15+ messages in thread
From: David Ahern @ 2013-09-28 19:13 UTC (permalink / raw)
  To: acme, linux-kernel
  Cc: David Ahern, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra,
	Jiri Olsa, Namhyung Kim, Stephane Eranian

Similar to other findnew based methods if the requested
object is not found, add it to the list.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Stephane Eranian <eranian@google.com>
---
 tools/perf/util/intlist.c |   10 ++++++++++
 tools/perf/util/intlist.h |    1 +
 2 files changed, 11 insertions(+)

diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c
index 826d7b3..60d7da5 100644
--- a/tools/perf/util/intlist.c
+++ b/tools/perf/util/intlist.c
@@ -74,6 +74,16 @@ struct int_node *intlist__find(struct intlist *ilist, int i)
 	return node;
 }
 
+struct int_node *intlist__findnew(struct intlist *ilist, int i)
+{
+	struct int_node *node = intlist__find(ilist, i);
+
+	if ((node == NULL) && (intlist__add(ilist, i) == 0))
+		node = intlist__find(ilist, i);
+
+	return node;
+}
+
 static int intlist__parse_list(struct intlist *ilist, const char *s)
 {
 	char *sep;
diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h
index 0eb00ac..aa6877d 100644
--- a/tools/perf/util/intlist.h
+++ b/tools/perf/util/intlist.h
@@ -24,6 +24,7 @@ int intlist__add(struct intlist *ilist, int i);
 
 struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx);
 struct int_node *intlist__find(struct intlist *ilist, int i);
+struct int_node *intlist__findnew(struct intlist *ilist, int i);
 
 static inline bool intlist__has_entry(struct intlist *ilist, int i)
 {
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 7/7] perf trace: Add summary option to dump syscall statistics
  2013-09-28 19:12 [PATCH 0/7] perf trace enhancements David Ahern
                   ` (5 preceding siblings ...)
  2013-09-28 19:13 ` [PATCH 6/7] perf util: Add findnew method to intlist David Ahern
@ 2013-09-28 19:13 ` David Ahern
  2013-10-08  1:44 ` [PATCH 0/7] perf trace enhancements David Ahern
  7 siblings, 0 replies; 15+ messages in thread
From: David Ahern @ 2013-09-28 19:13 UTC (permalink / raw)
  To: acme, linux-kernel
  Cc: David Ahern, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra,
	Jiri Olsa, Namhyung Kim, Stephane Eranian

When enabled dumps a summary of all syscalls by task with the usual
statistics -- min, max, average and relative stddev.

For example,

make - 26341 :       3344   [ 17.4% ]      0.000 ms

                read :   52    0.000    4.802    0.644   30.08
               write :   20    0.004    0.036    0.010   21.72
                open :   24    0.003    0.046    0.014   23.68
               close :   64    0.002    0.055    0.008   22.53
                stat : 2714    0.002    0.222    0.004    4.47
               fstat :   18    0.001    0.041    0.006   46.26
                mmap :   30    0.003    0.009    0.006    5.71
            mprotect :    8    0.006    0.039    0.016   32.16
              munmap :   12    0.007    0.077    0.020   38.25
                 brk :   48    0.002    0.014    0.004   10.18
        rt_sigaction :   18    0.002    0.002    0.002    2.11
      rt_sigprocmask :   60    0.002    0.128    0.010   32.88
              access :    2    0.006    0.006    0.006    0.00
                pipe :   12    0.004    0.048    0.013   35.98
               vfork :   34    0.448    0.980    0.692    3.04
              execve :   20    0.000    0.387    0.046   56.66
               wait4 :   34    0.017  9923.287  593.221   68.45
               fcntl :    8    0.001    0.041    0.013   48.79
            getdents :   48    0.002    0.079    0.013   19.62
              getcwd :    2    0.005    0.005    0.005    0.00
               chdir :    2    0.070    0.070    0.070    0.00
           getrlimit :    2    0.045    0.045    0.045    0.00
          arch_prctl :    2    0.002    0.002    0.002    0.00
           setrlimit :    2    0.002    0.002    0.002    0.00
              openat :   94    0.003    0.005    0.003    2.11

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Stephane Eranian <eranian@google.com>
---
 tools/perf/Documentation/perf-trace.txt |    4 ++
 tools/perf/builtin-trace.c              |  104 ++++++++++++++++++++++++++++---
 2 files changed, 100 insertions(+), 8 deletions(-)

diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 6728b00..e7ffdfc 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -97,6 +97,10 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
 	Show tool stats such as number of times fd->pathname was discovered thru
 	hooking the open syscall return + vfs_getname or via reading /proc/pid/fd, etc.
 
+--summary::
+	Show a summary of syscalls by thread with min, max, and average times (in
+    msec) and relative stddev.
+
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-script[1]
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index ab42148..35f7bb4 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -10,6 +10,7 @@
 #include "util/strlist.h"
 #include "util/intlist.h"
 #include "util/thread_map.h"
+#include "util/stat.h"
 
 #include <libaudit.h>
 #include <stdlib.h>
@@ -846,6 +847,8 @@ struct thread_trace {
 		int	  max;
 		char	  **table;
 	} paths;
+
+	struct intlist *syscall_stats;
 };
 
 static struct thread_trace *thread_trace__new(void)
@@ -855,6 +858,8 @@ static struct thread_trace *thread_trace__new(void)
 	if (ttrace)
 		ttrace->paths.max = -1;
 
+	ttrace->syscall_stats = intlist__new(NULL);
+
 	return ttrace;
 }
 
@@ -907,6 +912,7 @@ struct trace {
 	bool			multiple_threads;
 	bool			show_comm;
 	bool			show_tool_stats;
+	bool            summary;
 	double			duration_filter;
 	double			runtime_ms;
 	struct {
@@ -1293,6 +1299,32 @@ out_cant_read:
 	return NULL;
 }
 
+static void thread__update_stats(struct thread_trace *ttrace,
+				 int id, struct perf_sample *sample)
+{
+	struct int_node *inode;
+	struct stats *stats;
+	u64 duration = 0;
+
+	inode = intlist__findnew(ttrace->syscall_stats, id);
+	if (inode == NULL)
+		return;
+
+	stats = inode->priv;
+	if (stats == NULL) {
+		stats = malloc(sizeof(struct stats));
+		if (stats == NULL)
+			return;
+		init_stats(stats);
+		inode->priv = stats;
+	}
+
+	if (ttrace->entry_time && sample->time > ttrace->entry_time)
+		duration = sample->time - ttrace->entry_time;
+
+	update_stats(stats, duration);
+}
+
 static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
 			    struct perf_sample *sample)
 {
@@ -1370,6 +1402,9 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
 	if (ttrace == NULL)
 		return -1;
 
+	if (trace->summary)
+		thread__update_stats(ttrace, id, sample);
+
 	ret = perf_evsel__intval(evsel, sample, "ret");
 
 	if (id == trace->audit.open_id && ret >= 0 && trace->last_vfs_getname) {
@@ -1485,8 +1520,10 @@ static int trace__process_sample(struct perf_tool *tool,
 	if (!trace->full_time && trace->base_time == 0)
 		trace->base_time = sample->time;
 
-	if (handler)
+	if (handler) {
+		++trace->nr_events;
 		handler(trace, evsel, sample);
+	}
 
 	return err;
 }
@@ -1565,6 +1602,8 @@ static int trace__record(int argc, const char **argv)
 	return cmd_record(i, rec_argv, NULL);
 }
 
+static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp);
+
 static int trace__run(struct trace *trace, int argc, const char **argv)
 {
 	struct perf_evlist *evlist = perf_evlist__new();
@@ -1700,6 +1739,9 @@ again:
 		goto again;
 
 out_unmap_evlist:
+	if (!err && trace->summary)
+		trace__fprintf_thread_summary(trace, trace->output);
+
 	if (trace->show_tool_stats) {
 		fprintf(trace->output,
 			"Stats:\n "
@@ -1782,6 +1824,9 @@ static int trace__replay(struct trace *trace)
 	if (err)
 		pr_err("Failed to process events, error %d", err);
 
+	else if (trace->summary)
+		trace__fprintf_thread_summary(trace, trace->output);
+
 out:
 	perf_session__delete(session);
 
@@ -1792,10 +1837,53 @@ static size_t trace__fprintf_threads_header(FILE *fp)
 {
 	size_t printed;
 
-	printed  = fprintf(fp, "\n _____________________________________________________________________\n");
-	printed += fprintf(fp," __)    Summary of events    (__\n\n");
-	printed += fprintf(fp,"              [ task - pid ]     [ events ] [ ratio ]  [ runtime ]\n");
-	printed += fprintf(fp," _____________________________________________________________________\n\n");
+	printed  = fprintf(fp, "\n _____________________________________________________________________________\n");
+	printed += fprintf(fp, " __)    Summary of events    (__\n\n");
+	printed += fprintf(fp, "              [ task - pid ]     [ events ] [ ratio ]  [ runtime ]\n");
+	printed += fprintf(fp, "                                  syscall  count    min     max    avg  stddev\n");
+	printed += fprintf(fp, "                                                   msec    msec   msec     %%\n");
+	printed += fprintf(fp, " _____________________________________________________________________________\n\n");
+
+	return printed;
+}
+
+static size_t thread__dump_stats(struct thread_trace *ttrace,
+				 struct trace *trace, FILE *fp)
+{
+	struct stats *stats;
+	size_t printed = 0;
+	struct syscall *sc;
+	struct int_node *inode = intlist__first(ttrace->syscall_stats);
+
+	if (inode == NULL)
+		return 0;
+
+	printed += fprintf(fp, "\n");
+
+	/* each int_node is a syscall */
+	while (inode) {
+		stats = inode->priv;
+		if (stats) {
+			double min = (double)(stats->min) / NSEC_PER_MSEC;
+			double max = (double)(stats->max) / NSEC_PER_MSEC;
+			double avg = avg_stats(stats);
+			double pct;
+			u64 n = (u64) stats->n;
+
+			pct = avg ? 100.0 * stddev_stats(stats)/avg : 0.0;
+			avg /= NSEC_PER_MSEC;
+
+			sc = &trace->syscalls.table[inode->i];
+			printed += fprintf(fp, "%24s  %14s : ", "", sc->name);
+			printed += fprintf(fp, "%4" PRIu64 "  %7.3f  %7.3f",
+					   n, min, max);
+			printed += fprintf(fp, "  %7.3f  %6.2f\n", avg, pct);
+		}
+
+		inode = intlist__next(inode);
+	}
+
+	printed += fprintf(fp, "\n\n");
 
 	return printed;
 }
@@ -1834,6 +1922,7 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv)
 	printed += fprintf(fp, " - %-5d :%11lu   [", thread->tid, ttrace->nr_events);
 	printed += color_fprintf(fp, color, "%5.1f%%", ratio);
 	printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
+	printed += thread__dump_stats(ttrace, trace, fp);
 
 	data->printed += printed;
 
@@ -1941,6 +2030,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_INCR('v', "verbose", &verbose, "be more verbose"),
 	OPT_BOOLEAN('T', "time", &trace.full_time,
 		    "Show full timestamp, not time relative to first start"),
+	OPT_BOOLEAN(0, "summary", &trace.summary,
+		    "Show syscall summary with statistics"),
 	OPT_END()
 	};
 	int err;
@@ -1996,9 +2087,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 	else
 		err = trace__run(&trace, argc, argv);
 
-	if (trace.sched && !err)
-		trace__fprintf_thread_summary(&trace, trace.output);
-
 out_close:
 	if (output_name != NULL)
 		fclose(trace.output);
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/7] perf trace enhancements
  2013-09-28 19:12 [PATCH 0/7] perf trace enhancements David Ahern
                   ` (6 preceding siblings ...)
  2013-09-28 19:13 ` [PATCH 7/7] perf trace: Add summary option to dump syscall statistics David Ahern
@ 2013-10-08  1:44 ` David Ahern
  7 siblings, 0 replies; 15+ messages in thread
From: David Ahern @ 2013-10-08  1:44 UTC (permalink / raw)
  To: acme; +Cc: linux-kernel

On 9/28/13 1:12 PM, David Ahern wrote:
> Hi Arnaldo:
>
> Some more enhancements to perf-trace. It is based on your perf/trace
> branch to keep the conflicts down based on the work you are doing.
>
> David Ahern (7):
>    perf util: Add machine method to loop over threads and invoke handler
>    perf trace: Use new machine method to loop over threads
>    perf trace: Fix comm resolution when reading events from file
>    perf trace: Add record option
>    perf util: Add priv variable to intlist
>    perf util: Add findnew method to intlist
>    perf trace: Add summary option to dump syscall statistics

Any comments on the enhancements?


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 6/7] perf util: Add findnew method to intlist
  2013-09-28 19:13 ` [PATCH 6/7] perf util: Add findnew method to intlist David Ahern
@ 2013-10-08 13:22   ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 15+ messages in thread
From: Arnaldo Carvalho de Melo @ 2013-10-08 13:22 UTC (permalink / raw)
  To: David Ahern
  Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra,
	Jiri Olsa, Namhyung Kim, Stephane Eranian

Em Sat, Sep 28, 2013 at 01:13:03PM -0600, David Ahern escreveu:
> Similar to other findnew based methods if the requested
> object is not found, add it to the list.

> +struct int_node *intlist__findnew(struct intlist *ilist, int i)
> +{
> +	struct int_node *node = intlist__find(ilist, i);
> +
> +	if ((node == NULL) && (intlist__add(ilist, i) == 0))
> +		node = intlist__find(ilist, i);
> +
> +	return node;


This is what I should have pointed out earlier: Can't we have a
find_and_add_if_not_found routine as we have elsewhere?

Calling intlist__find() after intlist__add() looks really ugly :-\

Please take a look at my perf/core branch, several patches of this
series are there, one with minor change.

- Arnaldo

> +}
> +
>  static int intlist__parse_list(struct intlist *ilist, const char *s)
>  {
>  	char *sep;
> diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h
> index 0eb00ac..aa6877d 100644
> --- a/tools/perf/util/intlist.h
> +++ b/tools/perf/util/intlist.h
> @@ -24,6 +24,7 @@ int intlist__add(struct intlist *ilist, int i);
>  
>  struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx);
>  struct int_node *intlist__find(struct intlist *ilist, int i);
> +struct int_node *intlist__findnew(struct intlist *ilist, int i);
>  
>  static inline bool intlist__has_entry(struct intlist *ilist, int i)
>  {
> -- 
> 1.7.10.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [tip:perf/core] perf trace: Fix comm resolution when reading events from file
  2013-09-28 19:13 ` [PATCH 3/7] perf trace: Fix comm resolution when reading events from file David Ahern
@ 2013-10-15  5:30   ` tip-bot for David Ahern
  0 siblings, 0 replies; 15+ messages in thread
From: tip-bot for David Ahern @ 2013-10-15  5:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, hpa, mingo, a.p.zijlstra,
	namhyung.kim, jolsa, fweisbec, dsahern, tglx

Commit-ID:  8fb598e5a3b0ac213012e8461a309843ba0f2e74
Gitweb:     http://git.kernel.org/tip/8fb598e5a3b0ac213012e8461a309843ba0f2e74
Author:     David Ahern <dsahern@gmail.com>
AuthorDate: Sat, 28 Sep 2013 13:13:00 -0600
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 11 Oct 2013 12:17:48 -0300

perf trace: Fix comm resolution when reading events from file

Task comm's are getting lost when processing events from a file. The
problem is that the trace struct used by the live processing has its
host machine and the perf-session used for file based processing has its
host machine.  Fix by having both references point to the same machine.

Before:

     0.030 ( 0.001 ms): :27743/27743 brk( ...
     0.057 ( 0.004 ms): :27743/27743 mmap(len: 4096, prot: READ|WRITE, flags: ...
     0.075 ( 0.006 ms): :27743/27743 access(filename: 0x7f3809fbce00, mode: R ...
     0.091 ( 0.005 ms): :27743/27743 open(filename: 0x7f3809fba14c, flags: CLOEXEC ...
...

After:
     0.030 ( 0.001 ms): make/27743 brk( ...
     0.057 ( 0.004 ms): make/27743 mmap(len: 4096, prot: READ|WRITE, flags: ...
     0.075 ( 0.006 ms): make/27743 access(filename: 0x7f3809fbce00, mode: R ...
     0.091 ( 0.005 ms): make/27743 open(filename: 0x7f3809fba14c, flags: CLOEXEC ...
...

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1380395584-9025-4-git-send-email-dsahern@gmail.com
[ Moved creation of new host machine to a separate constructor: machine__new_host() ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-trace.c | 25 +++++++++++++------------
 tools/perf/util/machine.c  | 17 +++++++++++++++++
 tools/perf/util/machine.h  |  1 +
 3 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index fcc157f..5776b5f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -906,7 +906,7 @@ struct trace {
 		struct syscall  *table;
 	} syscalls;
 	struct perf_record_opts opts;
-	struct machine		host;
+	struct machine		*host;
 	u64			base_time;
 	bool			full_time;
 	FILE			*output;
@@ -1083,16 +1083,17 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
 	if (err)
 		return err;
 
-	machine__init(&trace->host, "", HOST_KERNEL_ID);
-	machine__create_kernel_maps(&trace->host);
+	trace->host = machine__new_host();
+	if (trace->host == NULL)
+		return -ENOMEM;
 
 	if (perf_target__has_task(&trace->opts.target)) {
 		err = perf_event__synthesize_thread_map(&trace->tool, evlist->threads,
 							trace__tool_process,
-							&trace->host);
+							trace->host);
 	} else {
 		err = perf_event__synthesize_threads(&trace->tool, trace__tool_process,
-						     &trace->host);
+						     trace->host);
 	}
 
 	if (err)
@@ -1304,8 +1305,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
 	if (sc->filtered)
 		return 0;
 
-	thread = machine__findnew_thread(&trace->host, sample->pid,
-					 sample->tid);
+	thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
 	ttrace = thread__trace(thread, trace->output);
 	if (ttrace == NULL)
 		return -1;
@@ -1357,8 +1357,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
 	if (sc->filtered)
 		return 0;
 
-	thread = machine__findnew_thread(&trace->host, sample->pid,
-					 sample->tid);
+	thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
 	ttrace = thread__trace(thread, trace->output);
 	if (ttrace == NULL)
 		return -1;
@@ -1414,7 +1413,7 @@ static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evs
 {
         u64 runtime = perf_evsel__intval(evsel, sample, "runtime");
 	double runtime_ms = (double)runtime / NSEC_PER_MSEC;
-	struct thread *thread = machine__findnew_thread(&trace->host,
+	struct thread *thread = machine__findnew_thread(trace->host,
 							sample->pid,
 							sample->tid);
 	struct thread_trace *ttrace = thread__trace(thread, trace->output);
@@ -1597,7 +1596,7 @@ again:
 				trace->base_time = sample.time;
 
 			if (type != PERF_RECORD_SAMPLE) {
-				trace__process_event(trace, &trace->host, event);
+				trace__process_event(trace, trace->host, event);
 				continue;
 			}
 
@@ -1681,6 +1680,8 @@ static int trace__replay(struct trace *trace)
 	if (session == NULL)
 		return -ENOMEM;
 
+	trace->host = &session->machines.host;
+
 	err = perf_session__set_tracepoints_handlers(session, handlers);
 	if (err)
 		goto out;
@@ -1728,7 +1729,7 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
 	size_t printed = trace__fprintf_threads_header(fp);
 	struct rb_node *nd;
 
-	for (nd = rb_first(&trace->host.threads); nd; nd = rb_next(nd)) {
+	for (nd = rb_first(&trace->host->threads); nd; nd = rb_next(nd)) {
 		struct thread *thread = rb_entry(nd, struct thread, rb_node);
 		struct thread_trace *ttrace = thread->priv;
 		const char *color;
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index ddf917b..fc14f9b 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -46,6 +46,23 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
 	return 0;
 }
 
+struct machine *machine__new_host(void)
+{
+	struct machine *machine = malloc(sizeof(*machine));
+
+	if (machine != NULL) {
+		machine__init(machine, "", HOST_KERNEL_ID);
+
+		if (machine__create_kernel_maps(machine) < 0)
+			goto out_delete;
+	}
+
+	return machine;
+out_delete:
+	free(machine);
+	return NULL;
+}
+
 static void dsos__delete(struct list_head *dsos)
 {
 	struct dso *pos, *n;
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 58a6be1..5150d5e 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -74,6 +74,7 @@ char *machine__mmap_name(struct machine *machine, char *bf, size_t size);
 void machines__set_symbol_filter(struct machines *machines,
 				 symbol_filter_t symbol_filter);
 
+struct machine *machine__new_host(void);
 int machine__init(struct machine *machine, const char *root_dir, pid_t pid);
 void machine__exit(struct machine *machine);
 void machine__delete_dead_threads(struct machine *machine);

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip:perf/core] perf trace: Add record option
  2013-09-28 19:13 ` [PATCH 4/7] perf trace: Add record option David Ahern
@ 2013-10-15  5:30   ` tip-bot for David Ahern
  0 siblings, 0 replies; 15+ messages in thread
From: tip-bot for David Ahern @ 2013-10-15  5:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, hpa, mingo, a.p.zijlstra,
	namhyung.kim, jolsa, fweisbec, dsahern, tglx

Commit-ID:  5e2485b1a2813faa6b80007c653f8bbbed9457ee
Gitweb:     http://git.kernel.org/tip/5e2485b1a2813faa6b80007c653f8bbbed9457ee
Author:     David Ahern <dsahern@gmail.com>
AuthorDate: Sat, 28 Sep 2013 13:13:01 -0600
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 11 Oct 2013 12:17:49 -0300

perf trace: Add record option

The record option is a convience alias to include the -e raw_syscalls:*
argument to perf-record. All other options are passed to perf-record's
handler. Resulting data file can be analyzed by perf-trace -i.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1380395584-9025-5-git-send-email-dsahern@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-trace.txt | 12 +++++++++---
 tools/perf/builtin-trace.c              | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 7f70d36..1a22486 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -9,6 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'perf trace'
+'perf trace record'
 
 DESCRIPTION
 -----------
@@ -16,9 +17,14 @@ This command will show the events associated with the target, initially
 syscalls, but other system events like pagefaults, task lifetime events,
 scheduling events, etc.
 
-Initially this is a live mode only tool, but eventually will work with
-perf.data files like the other tools, allowing a detached 'record' from
-analysis phases.
+This is a live mode tool in addition to working with perf.data files like
+the other perf tools. Files can be generated using the 'perf record' command
+but the session needs to include the raw_syscalls events (-e 'raw_syscalls:*').
+Alernatively, the 'perf trace record' can be used as a shortcut to
+automatically include the raw_syscalls events when writing events to a file.
+
+The following options apply to perf trace; options to perf trace record are
+found in the perf record man page.
 
 OPTIONS
 -------
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 5776b5f..1e2368f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1501,6 +1501,33 @@ static int parse_target_str(struct trace *trace)
 	return 0;
 }
 
+static int trace__record(int argc, const char **argv)
+{
+	unsigned int rec_argc, i, j;
+	const char **rec_argv;
+	const char * const record_args[] = {
+		"record",
+		"-R",
+		"-m", "1024",
+		"-c", "1",
+		"-e", "raw_syscalls:sys_enter,raw_syscalls:sys_exit",
+	};
+
+	rec_argc = ARRAY_SIZE(record_args) + argc;
+	rec_argv = calloc(rec_argc + 1, sizeof(char *));
+
+	if (rec_argv == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(record_args); i++)
+		rec_argv[i] = record_args[i];
+
+	for (j = 0; j < (unsigned int)argc; j++, i++)
+		rec_argv[i] = argv[j];
+
+	return cmd_record(i, rec_argv, NULL);
+}
+
 static int trace__run(struct trace *trace, int argc, const char **argv)
 {
 	struct perf_evlist *evlist = perf_evlist__new();
@@ -1788,6 +1815,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 	const char * const trace_usage[] = {
 		"perf trace [<options>] [<command>]",
 		"perf trace [<options>] -- <command> [<options>]",
+		"perf trace record [<options>] [<command>]",
+		"perf trace record [<options>] -- <command> [<options>]",
 		NULL
 	};
 	struct trace trace = {
@@ -1844,6 +1873,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 	int err;
 	char bf[BUFSIZ];
 
+	if ((argc > 1) && (strcmp(argv[1], "record") == 0))
+		return trace__record(argc-2, &argv[2]);
+
 	argc = parse_options(argc, argv, trace_options, trace_usage, 0);
 
 	if (output_name != NULL) {

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip:perf/core] perf machine: Add method to loop over threads and invoke handler
  2013-09-28 19:12 ` [PATCH 1/7] perf util: Add machine method to loop over threads and invoke handler David Ahern
@ 2013-10-15  5:30   ` tip-bot for David Ahern
  0 siblings, 0 replies; 15+ messages in thread
From: tip-bot for David Ahern @ 2013-10-15  5:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, hpa, mingo, a.p.zijlstra,
	namhyung.kim, jolsa, fweisbec, dsahern, tglx

Commit-ID:  35feee19f9fda7447f51073b5be3f6d082b508f5
Gitweb:     http://git.kernel.org/tip/35feee19f9fda7447f51073b5be3f6d082b508f5
Author:     David Ahern <dsahern@gmail.com>
AuthorDate: Sat, 28 Sep 2013 13:12:58 -0600
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 11 Oct 2013 12:17:51 -0300

perf machine: Add method to loop over threads and invoke handler

Loop over all threads within a machine - including threads moved to the
dead threads list -- and invoked a function.

This allows commands to run some specific function on each thread (eg.,
dump statistics) yet hides how the threads are maintained within the
machine.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1380395584-9025-2-git-send-email-dsahern@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/machine.c | 23 +++++++++++++++++++++++
 tools/perf/util/machine.h |  4 ++++
 2 files changed, 27 insertions(+)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index fc14f9b..901397a 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1393,3 +1393,26 @@ int machine__resolve_callchain(struct machine *machine,
 				   sample);
 
 }
+
+int machine__for_each_thread(struct machine *machine,
+			     int (*fn)(struct thread *thread, void *p),
+			     void *priv)
+{
+	struct rb_node *nd;
+	struct thread *thread;
+	int rc = 0;
+
+	for (nd = rb_first(&machine->threads); nd; nd = rb_next(nd)) {
+		thread = rb_entry(nd, struct thread, rb_node);
+		rc = fn(thread, priv);
+		if (rc != 0)
+			return rc;
+	}
+
+	list_for_each_entry(thread, &machine->dead_threads, node) {
+		rc = fn(thread, priv);
+		if (rc != 0)
+			return rc;
+	}
+	return rc;
+}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 5150d5e..d44c09b 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -166,4 +166,8 @@ void machines__destroy_kernel_maps(struct machines *machines);
 
 size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);
 
+int machine__for_each_thread(struct machine *machine,
+			     int (*fn)(struct thread *thread, void *p),
+			     void *priv);
+
 #endif /* __PERF_MACHINE_H */

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip:perf/core] perf trace: Use new machine method to loop over threads
  2013-09-28 19:12 ` [PATCH 2/7] perf trace: Use new machine method to loop over threads David Ahern
@ 2013-10-15  5:30   ` tip-bot for David Ahern
  0 siblings, 0 replies; 15+ messages in thread
From: tip-bot for David Ahern @ 2013-10-15  5:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, hpa, mingo, a.p.zijlstra,
	namhyung.kim, jolsa, fweisbec, dsahern, tglx

Commit-ID:  896cbb56bfee6ad99e0ee1b8209dc678f1a49f5a
Gitweb:     http://git.kernel.org/tip/896cbb56bfee6ad99e0ee1b8209dc678f1a49f5a
Author:     David Ahern <dsahern@gmail.com>
AuthorDate: Sat, 28 Sep 2013 13:12:59 -0600
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 11 Oct 2013 12:17:53 -0300

perf trace: Use new machine method to loop over threads

Use the new machine method that loops over threads to dump summary data.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1380395584-9025-3-git-send-email-dsahern@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-trace.c | 76 +++++++++++++++++++++++++++++-----------------
 1 file changed, 48 insertions(+), 28 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 1e2368f..addc3e1 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1751,37 +1751,57 @@ static size_t trace__fprintf_threads_header(FILE *fp)
 	return printed;
 }
 
+/* struct used to pass data to per-thread function */
+struct summary_data {
+	FILE *fp;
+	struct trace *trace;
+	size_t printed;
+};
+
+static int trace__fprintf_one_thread(struct thread *thread, void *priv)
+{
+	struct summary_data *data = priv;
+	FILE *fp = data->fp;
+	size_t printed = data->printed;
+	struct trace *trace = data->trace;
+	struct thread_trace *ttrace = thread->priv;
+	const char *color;
+	double ratio;
+
+	if (ttrace == NULL)
+		return 0;
+
+	ratio = (double)ttrace->nr_events / trace->nr_events * 100.0;
+
+	color = PERF_COLOR_NORMAL;
+	if (ratio > 50.0)
+		color = PERF_COLOR_RED;
+	else if (ratio > 25.0)
+		color = PERF_COLOR_GREEN;
+	else if (ratio > 5.0)
+		color = PERF_COLOR_YELLOW;
+
+	printed += color_fprintf(fp, color, "%20s", thread->comm);
+	printed += fprintf(fp, " - %-5d :%11lu   [", thread->tid, ttrace->nr_events);
+	printed += color_fprintf(fp, color, "%5.1f%%", ratio);
+	printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
+
+	data->printed += printed;
+
+	return 0;
+}
+
 static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
 {
-	size_t printed = trace__fprintf_threads_header(fp);
-	struct rb_node *nd;
-
-	for (nd = rb_first(&trace->host->threads); nd; nd = rb_next(nd)) {
-		struct thread *thread = rb_entry(nd, struct thread, rb_node);
-		struct thread_trace *ttrace = thread->priv;
-		const char *color;
-		double ratio;
-
-		if (ttrace == NULL)
-			continue;
-
-		ratio = (double)ttrace->nr_events / trace->nr_events * 100.0;
-
-		color = PERF_COLOR_NORMAL;
-		if (ratio > 50.0)
-			color = PERF_COLOR_RED;
-		else if (ratio > 25.0)
-			color = PERF_COLOR_GREEN;
-		else if (ratio > 5.0)
-			color = PERF_COLOR_YELLOW;
-
-		printed += color_fprintf(fp, color, "%20s", thread->comm);
-		printed += fprintf(fp, " - %-5d :%11lu   [", thread->tid, ttrace->nr_events);
-		printed += color_fprintf(fp, color, "%5.1f%%", ratio);
-		printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms);
-	}
+	struct summary_data data = {
+		.fp = fp,
+		.trace = trace
+	};
+	data.printed = trace__fprintf_threads_header(fp);
 
-	return printed;
+	machine__for_each_thread(trace->host, trace__fprintf_one_thread, &data);
+
+	return data.printed;
 }
 
 static int trace__set_duration(const struct option *opt, const char *str,

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [tip:perf/core] perf intlist: Add priv member
  2013-09-28 19:13 ` [PATCH 5/7] perf util: Add priv variable to intlist David Ahern
@ 2013-10-15  5:31   ` tip-bot for David Ahern
  0 siblings, 0 replies; 15+ messages in thread
From: tip-bot for David Ahern @ 2013-10-15  5:31 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, eranian, hpa, mingo, a.p.zijlstra,
	namhyung.kim, jolsa, fweisbec, dsahern, tglx

Commit-ID:  2969b12993ca7a8b9692048431e075a67815002d
Gitweb:     http://git.kernel.org/tip/2969b12993ca7a8b9692048431e075a67815002d
Author:     David Ahern <dsahern@gmail.com>
AuthorDate: Sat, 28 Sep 2013 13:13:02 -0600
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 11 Oct 2013 12:17:55 -0300

perf intlist: Add priv member

Allows commands to leverage intlist infrastructure for opaque
structures.

For example an upcoming perf-trace change will use this as a means of
tracking syscalls statistics by task.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1380395584-9025-6-git-send-email-dsahern@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/intlist.c | 1 +
 tools/perf/util/intlist.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c
index 11a8d86..826d7b3 100644
--- a/tools/perf/util/intlist.c
+++ b/tools/perf/util/intlist.c
@@ -20,6 +20,7 @@ static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
 
 	if (node != NULL) {
 		node->i = i;
+		node->priv = NULL;
 		rc = &node->rb_node;
 	}
 
diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h
index 62351da..0eb00ac 100644
--- a/tools/perf/util/intlist.h
+++ b/tools/perf/util/intlist.h
@@ -9,6 +9,7 @@
 struct int_node {
 	struct rb_node rb_node;
 	int i;
+	void *priv;
 };
 
 struct intlist {

^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2013-10-15  5:39 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-09-28 19:12 [PATCH 0/7] perf trace enhancements David Ahern
2013-09-28 19:12 ` [PATCH 1/7] perf util: Add machine method to loop over threads and invoke handler David Ahern
2013-10-15  5:30   ` [tip:perf/core] perf machine: Add " tip-bot for David Ahern
2013-09-28 19:12 ` [PATCH 2/7] perf trace: Use new machine method to loop over threads David Ahern
2013-10-15  5:30   ` [tip:perf/core] " tip-bot for David Ahern
2013-09-28 19:13 ` [PATCH 3/7] perf trace: Fix comm resolution when reading events from file David Ahern
2013-10-15  5:30   ` [tip:perf/core] " tip-bot for David Ahern
2013-09-28 19:13 ` [PATCH 4/7] perf trace: Add record option David Ahern
2013-10-15  5:30   ` [tip:perf/core] " tip-bot for David Ahern
2013-09-28 19:13 ` [PATCH 5/7] perf util: Add priv variable to intlist David Ahern
2013-10-15  5:31   ` [tip:perf/core] perf intlist: Add priv member tip-bot for David Ahern
2013-09-28 19:13 ` [PATCH 6/7] perf util: Add findnew method to intlist David Ahern
2013-10-08 13:22   ` Arnaldo Carvalho de Melo
2013-09-28 19:13 ` [PATCH 7/7] perf trace: Add summary option to dump syscall statistics David Ahern
2013-10-08  1:44 ` [PATCH 0/7] perf trace enhancements David Ahern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).