From: Namhyung Kim <[email protected]>
Since perf trace emits lots of messages on terminal, it'd better using
a pager.
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/builtin-trace.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index dec8ced61fb0..9fc4bed8837d 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2,6 +2,7 @@
#include "util/evlist.h"
#include "util/parse-options.h"
#include "util/thread_map.h"
+#include "util/cache.h"
#include "event-parse.h"
#include <libaudit.h>
@@ -336,5 +337,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
return err;
}
+ setup_pager();
+
return trace__run(&trace);
}
--
1.7.11.4
From: Namhyung Kim <[email protected]>
Other perf subcommands like record, top and stat use '-a' as a
shortcut for --all-cpus option. Just follow the convention. :)
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/builtin-trace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 231b60690ce9..8daac2eef5af 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -311,7 +311,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
"trace events on existing process id"),
OPT_STRING(0, "tid", &trace.opts.target.tid, "tid",
"trace events on existing thread id"),
- OPT_BOOLEAN(0, "all-cpus", &trace.opts.target.system_wide,
+ OPT_BOOLEAN('a', "all-cpus", &trace.opts.target.system_wide,
"system-wide collection from all CPUs"),
OPT_STRING(0, "cpu", &trace.opts.target.cpu_list, "cpu",
"list of cpus to monitor"),
--
1.7.11.4
From: Namhyung Kim <[email protected]>
Now perf trace is able to trace specified workload by forking it like
perf record does. And also finish the tracing if the workload quits
or gets SIGINT.
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/builtin-trace.c | 43 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 7 deletions(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 8daac2eef5af..e9e0eae8eabb 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -53,6 +53,13 @@ struct trace {
struct perf_record_opts opts;
};
+static bool done = false;
+
+static void sig_handler(int sig __maybe_unused)
+{
+ done = true;
+}
+
static int trace__read_syscall_info(struct trace *trace, int id)
{
char tp_name[128];
@@ -190,11 +197,12 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
return 0;
}
-static int trace__run(struct trace *trace)
+static int trace__run(struct trace *trace, int argc, const char **argv)
{
struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
struct perf_evsel *evsel;
int err = -1, i, nr_events = 0, before;
+ const bool forks = argc > 0;
if (evlist == NULL) {
printf("Not enough memory to run!\n");
@@ -215,6 +223,17 @@ static int trace__run(struct trace *trace)
perf_evlist__config_attrs(evlist, &trace->opts);
+ signal(SIGCHLD, sig_handler);
+ signal(SIGINT, sig_handler);
+
+ if (forks) {
+ err = perf_evlist__prepare_workload(evlist, &trace->opts, argv);
+ if (err < 0) {
+ printf("Couldn't run the workload!\n");
+ goto out_delete_evlist;
+ }
+ }
+
err = perf_evlist__open(evlist);
if (err < 0) {
printf("Couldn't create the events: %s\n", strerror(errno));
@@ -228,6 +247,10 @@ static int trace__run(struct trace *trace)
}
perf_evlist__enable(evlist);
+
+ if (forks)
+ perf_evlist__start_workload(evlist);
+
again:
before = nr_events;
@@ -273,8 +296,15 @@ again:
}
}
- if (nr_events == before)
+ if (nr_events == before) {
+ if (done)
+ goto out_delete_evlist;
+
poll(evlist->pollfd, evlist->nr_fds, -1);
+ }
+
+ if (done)
+ perf_evlist__disable(evlist);
goto again;
@@ -287,7 +317,8 @@ out:
int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
{
const char * const trace_usage[] = {
- "perf trace [<options>]",
+ "perf trace [<options>] [<command>]",
+ "perf trace [<options>] -- <command> [<options>]",
NULL
};
struct trace trace = {
@@ -327,8 +358,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
char bf[BUFSIZ];
argc = parse_options(argc, argv, trace_options, trace_usage, 0);
- if (argc)
- usage_with_options(trace_usage, trace_options);
err = perf_target__validate(&trace.opts.target);
if (err) {
@@ -344,10 +373,10 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
return err;
}
- if (perf_target__none(&trace.opts.target))
+ if (!argc && perf_target__none(&trace.opts.target))
trace.opts.target.system_wide = true;
setup_pager();
- return trace__run(&trace);
+ return trace__run(&trace, argc, argv);
}
--
1.7.11.4
From: Namhyung Kim <[email protected]>
When no target cpu/user/task option is given, perf trace will do its
job system wide for all online cpus. Make it explicit to reduce
possible confusion when reading code.
No functional changes intended.
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/builtin-trace.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 7bb7e757c745..231b60690ce9 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -344,6 +344,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
return err;
}
+ if (perf_target__none(&trace.opts.target))
+ trace.opts.target.system_wide = true;
+
setup_pager();
return trace__run(&trace);
--
1.7.11.4
From: Namhyung Kim <[email protected]>
Those target options are mutually exclusive so check it before setting
up target thread/cpu maps.
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/builtin-trace.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 9fc4bed8837d..7bb7e757c745 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -324,14 +324,21 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_END()
};
int err;
+ char bf[BUFSIZ];
argc = parse_options(argc, argv, trace_options, trace_usage, 0);
if (argc)
usage_with_options(trace_usage, trace_options);
+ err = perf_target__validate(&trace.opts.target);
+ if (err) {
+ perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
+ printf("%s", bf);
+ return err;
+ }
+
err = perf_target__parse_uid(&trace.opts.target);
if (err) {
- char bf[BUFSIZ];
perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
printf("%s", bf);
return err;
--
1.7.11.4
Em Fri, Oct 05, 2012 at 02:02:12PM +0900, Namhyung Kim escreveu:
> From: Namhyung Kim <[email protected]>
>
> Since perf trace emits lots of messages on terminal, it'd better using
> a pager.
Humm, I'm used to the strace behaviour, i.e. free flow of events, unsure
if using the pager in this specific case is right, perhaps it should be
optional.
In the TUI case, when we get to implement it there, I think that we can
go to/from pager mode, expanding callchains for pagefaults and other
events, for instance.
- Arnaldo
Commit-ID: 32caf0d1fe14eb69191e7828701e381b1edb340d
Gitweb: http://git.kernel.org/tip/32caf0d1fe14eb69191e7828701e381b1edb340d
Author: Namhyung Kim <[email protected]>
AuthorDate: Fri, 5 Oct 2012 14:02:13 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 5 Oct 2012 12:47:54 -0300
perf trace: Validate target task/user/cpu argument
Those target options are mutually exclusive so check it before setting
up target thread/cpu maps.
Signed-off-by: Namhyung Kim <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-trace.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index dec8ced..f01fa6f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -323,14 +323,21 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_END()
};
int err;
+ char bf[BUFSIZ];
argc = parse_options(argc, argv, trace_options, trace_usage, 0);
if (argc)
usage_with_options(trace_usage, trace_options);
+ err = perf_target__validate(&trace.opts.target);
+ if (err) {
+ perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
+ printf("%s", bf);
+ return err;
+ }
+
err = perf_target__parse_uid(&trace.opts.target);
if (err) {
- char bf[BUFSIZ];
perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));
printf("%s", bf);
return err;
Commit-ID: ee76120e2d13a2d4eb0cc88da8a8e7f7909cc276
Gitweb: http://git.kernel.org/tip/ee76120e2d13a2d4eb0cc88da8a8e7f7909cc276
Author: Namhyung Kim <[email protected]>
AuthorDate: Fri, 5 Oct 2012 14:02:14 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 5 Oct 2012 12:48:51 -0300
perf trace: Explicitly enable system-wide mode if no option is given
When no target cpu/user/task option is given, perf trace will do its job
system wide for all online cpus. Make it explicit to reduce possible
confusion when reading code.
No functional changes intended.
Signed-off-by: Namhyung Kim <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-trace.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index f01fa6f..da1183f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -343,5 +343,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
return err;
}
+ if (perf_target__none(&trace.opts.target))
+ trace.opts.target.system_wide = true;
+
return trace__run(&trace);
}
Commit-ID: f15eb531d351163f1ea697c2dd8f15b66b01d289
Gitweb: http://git.kernel.org/tip/f15eb531d351163f1ea697c2dd8f15b66b01d289
Author: Namhyung Kim <[email protected]>
AuthorDate: Fri, 5 Oct 2012 14:02:16 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 5 Oct 2012 12:51:27 -0300
perf trace: Add support for tracing workload given by command line
Now perf trace is able to trace specified workload by forking it like
perf record does. And also finish the tracing if the workload quits or
gets SIGINT.
Signed-off-by: Namhyung Kim <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-trace.c | 43 ++++++++++++++++++++++++++++++++++++-------
1 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index da1183f..4e9320b 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -52,6 +52,13 @@ struct trace {
struct perf_record_opts opts;
};
+static bool done = false;
+
+static void sig_handler(int sig __maybe_unused)
+{
+ done = true;
+}
+
static int trace__read_syscall_info(struct trace *trace, int id)
{
char tp_name[128];
@@ -189,11 +196,12 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
return 0;
}
-static int trace__run(struct trace *trace)
+static int trace__run(struct trace *trace, int argc, const char **argv)
{
struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
struct perf_evsel *evsel;
int err = -1, i, nr_events = 0, before;
+ const bool forks = argc > 0;
if (evlist == NULL) {
printf("Not enough memory to run!\n");
@@ -214,6 +222,17 @@ static int trace__run(struct trace *trace)
perf_evlist__config_attrs(evlist, &trace->opts);
+ signal(SIGCHLD, sig_handler);
+ signal(SIGINT, sig_handler);
+
+ if (forks) {
+ err = perf_evlist__prepare_workload(evlist, &trace->opts, argv);
+ if (err < 0) {
+ printf("Couldn't run the workload!\n");
+ goto out_delete_evlist;
+ }
+ }
+
err = perf_evlist__open(evlist);
if (err < 0) {
printf("Couldn't create the events: %s\n", strerror(errno));
@@ -227,6 +246,10 @@ static int trace__run(struct trace *trace)
}
perf_evlist__enable(evlist);
+
+ if (forks)
+ perf_evlist__start_workload(evlist);
+
again:
before = nr_events;
@@ -272,8 +295,15 @@ again:
}
}
- if (nr_events == before)
+ if (nr_events == before) {
+ if (done)
+ goto out_delete_evlist;
+
poll(evlist->pollfd, evlist->nr_fds, -1);
+ }
+
+ if (done)
+ perf_evlist__disable(evlist);
goto again;
@@ -286,7 +316,8 @@ out:
int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
{
const char * const trace_usage[] = {
- "perf trace [<options>]",
+ "perf trace [<options>] [<command>]",
+ "perf trace [<options>] -- <command> [<options>]",
NULL
};
struct trace trace = {
@@ -326,8 +357,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
char bf[BUFSIZ];
argc = parse_options(argc, argv, trace_options, trace_usage, 0);
- if (argc)
- usage_with_options(trace_usage, trace_options);
err = perf_target__validate(&trace.opts.target);
if (err) {
@@ -343,8 +372,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
return err;
}
- if (perf_target__none(&trace.opts.target))
+ if (!argc && perf_target__none(&trace.opts.target))
trace.opts.target.system_wide = true;
- return trace__run(&trace);
+ return trace__run(&trace, argc, argv);
}