diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-10-08 08:56:00 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-10-24 16:41:04 -0400 |
commit | ae9ed03579c9745e85a88e80522770df7ae5c9b7 (patch) | |
tree | beca78273c33e4c023d7514a14e9ab886e60392f | |
parent | 60c907abc635622964f7862c8f2977182124f89d (diff) |
perf trace: Add duration filter
Example:
[acme@sandy linux]$ perf trace --duration 0.025 usleep 1
2.221 ( 0.958 ms): 6724 execve(arg0: 140733557168278, arg1: 140733557178768, arg2: 16134304, arg3: 140733557167840, arg4: 7955998171588342573, arg5: 6723) = -2
3.690 ( 1.443 ms): 6724 execve(arg0: 140733557168295, arg1: 140733557178768, arg2: 16134304, arg3: 140733557167840, arg4: 7955998171588342573, arg5: 6723) = 0
3.979 ( 0.048 ms): 6724 open(filename: 208733843841, flags: 0, mode: 1 ) = 3
4.071 ( 0.075 ms): 6724 open(filename: 139744419925673, flags: 0, mode: 0 ) = 3
4.318 ( 0.056 ms): 6724 nanosleep(rqtp: 140734030404608, rmtp: 0 ) = 0
[acme@sandy linux]$ perf trace --duration 0.100 usleep 1
1.143 ( 1.021 ms): 6726 execve(arg0: 140736323962279, arg1: 140736323972752, arg2: 34926752, arg3: 140736323961824, arg4: 7955998171588342573, arg5: 6725) = 0
[acme@sandy linux]$
Cherry picked from tmp.perf/trace2 branch.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/n/tip-oslw2j2958we9qf0ctra4whd@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/Documentation/perf-trace.txt | 3 | ||||
-rw-r--r-- | tools/perf/builtin-trace.c | 32 |
2 files changed, 31 insertions, 4 deletions
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 3a2ae37310a9..38d4b682af0b 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt | |||
@@ -48,6 +48,9 @@ comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0- | |||
48 | In per-thread mode with inheritance mode on (default), Events are captured only when | 48 | In per-thread mode with inheritance mode on (default), Events are captured only when |
49 | the thread executes on the designated CPUs. Default is to monitor all CPUs. | 49 | the thread executes on the designated CPUs. Default is to monitor all CPUs. |
50 | 50 | ||
51 | --duration: | ||
52 | Show only events that had a duration greater than N.M ms. | ||
53 | |||
51 | SEE ALSO | 54 | SEE ALSO |
52 | -------- | 55 | -------- |
53 | linkperf:perf-record[1], linkperf:perf-script[1] | 56 | linkperf:perf-record[1], linkperf:perf-script[1] |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index ddb6e3721b1a..82ffa6c246d8 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -100,8 +100,14 @@ struct trace { | |||
100 | struct machine host; | 100 | struct machine host; |
101 | u64 base_time; | 101 | u64 base_time; |
102 | bool multiple_threads; | 102 | bool multiple_threads; |
103 | double duration_filter; | ||
103 | }; | 104 | }; |
104 | 105 | ||
106 | static bool trace__filter_duration(struct trace *trace, double t) | ||
107 | { | ||
108 | return t < (trace->duration_filter * NSEC_PER_MSEC); | ||
109 | } | ||
110 | |||
105 | static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp) | 111 | static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp) |
106 | { | 112 | { |
107 | double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC; | 113 | double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC; |
@@ -307,8 +313,10 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, | |||
307 | printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, args); | 313 | printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, args); |
308 | 314 | ||
309 | if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) { | 315 | if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) { |
310 | trace__fprintf_entry_head(trace, thread, 1, sample->time, stdout); | 316 | if (!trace->duration_filter) { |
311 | printf("%-70s\n", ttrace->entry_str); | 317 | trace__fprintf_entry_head(trace, thread, 1, sample->time, stdout); |
318 | printf("%-70s\n", ttrace->entry_str); | ||
319 | } | ||
312 | } else | 320 | } else |
313 | ttrace->entry_pending = true; | 321 | ttrace->entry_pending = true; |
314 | 322 | ||
@@ -333,8 +341,12 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, | |||
333 | 341 | ||
334 | ttrace->exit_time = sample->time; | 342 | ttrace->exit_time = sample->time; |
335 | 343 | ||
336 | if (ttrace->entry_time) | 344 | if (ttrace->entry_time) { |
337 | duration = sample->time - ttrace->entry_time; | 345 | duration = sample->time - ttrace->entry_time; |
346 | if (trace__filter_duration(trace, duration)) | ||
347 | goto out; | ||
348 | } else if (trace->duration_filter) | ||
349 | goto out; | ||
338 | 350 | ||
339 | trace__fprintf_entry_head(trace, thread, duration, sample->time, stdout); | 351 | trace__fprintf_entry_head(trace, thread, duration, sample->time, stdout); |
340 | 352 | ||
@@ -358,7 +370,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, | |||
358 | printf(") = %d", ret); | 370 | printf(") = %d", ret); |
359 | 371 | ||
360 | putchar('\n'); | 372 | putchar('\n'); |
361 | 373 | out: | |
362 | ttrace->entry_pending = false; | 374 | ttrace->entry_pending = false; |
363 | 375 | ||
364 | return 0; | 376 | return 0; |
@@ -495,6 +507,15 @@ out: | |||
495 | return err; | 507 | return err; |
496 | } | 508 | } |
497 | 509 | ||
510 | static int trace__set_duration(const struct option *opt, const char *str, | ||
511 | int unset __maybe_unused) | ||
512 | { | ||
513 | struct trace *trace = opt->value; | ||
514 | |||
515 | trace->duration_filter = atof(str); | ||
516 | return 0; | ||
517 | } | ||
518 | |||
498 | int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) | 519 | int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) |
499 | { | 520 | { |
500 | const char * const trace_usage[] = { | 521 | const char * const trace_usage[] = { |
@@ -533,6 +554,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) | |||
533 | "number of mmap data pages"), | 554 | "number of mmap data pages"), |
534 | OPT_STRING(0, "uid", &trace.opts.target.uid_str, "user", | 555 | OPT_STRING(0, "uid", &trace.opts.target.uid_str, "user", |
535 | "user to profile"), | 556 | "user to profile"), |
557 | OPT_CALLBACK(0, "duration", &trace, "float", | ||
558 | "show only events with duration > N.M ms", | ||
559 | trace__set_duration), | ||
536 | OPT_END() | 560 | OPT_END() |
537 | }; | 561 | }; |
538 | int err; | 562 | int err; |