diff options
author | David Ahern <dsa@cumulusnetworks.com> | 2016-11-29 12:15:44 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-12-01 11:02:52 -0500 |
commit | 853b74071110bed344bad1ca9d8de27731b1c574 (patch) | |
tree | d852f442df60e9ce8824f858fe3be1e639778f35 | |
parent | a91f4c473fa1655a2a5f1ceba46f76a95eef35bb (diff) |
perf sched timehist: Add option to specify time window of interest
Add option to allow user to control analysis window. e.g., collect data
for time window and analyze a segment of interest within that window.
Committer notes:
Testing it:
# perf sched record -a usleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 1.593 MB perf.data (25 samples) ]
#
# perf sched timehist | head -18
Samples do not have callchains.
time cpu task name wait time sch delay run time
[tid/pid] (msec) (msec) (msec)
------------- ------ --------------- --------- --------- --------
19818.635579 [0002] <idle> 0.000 0.000 0.000
19818.635613 [0000] perf[9116] 0.000 0.000 0.000
19818.635676 [0000] <idle> 0.000 0.000 0.063
19818.635678 [0000] rcuos/2[29] 0.000 0.002 0.001
19818.635696 [0002] perf[9117] 0.000 0.004 0.116
19818.635702 [0000] <idle> 0.001 0.000 0.024
19818.635709 [0002] migration/2[25] 0.000 0.003 0.012
19818.636263 [0000] usleep[9117] 0.005 0.000 0.560
19818.636316 [0000] <idle> 0.560 0.000 0.053
19818.636358 [0002] <idle> 0.129 0.000 0.649
19818.636358 [0000] usleep[9117] 0.053 0.002 0.042
#
# perf sched timehist --time 19818.635696,
Samples do not have callchains.
time cpu task name wait time sch delay run time
[tid/pid] (msec) (msec) (msec)
------------- ------ --------------- -------- --------- ---------
19818.635696 [0002] perf[9117] 0.000 0.120 0.000
19818.635702 [0000] <idle> 0.019 0.000 0.006
19818.635709 [0002] migration/2[25] 0.000 0.003 0.012
19818.636263 [0000] usleep[9117] 0.005 0.000 0.560
19818.636316 [0000] <idle> 0.560 0.000 0.053
19818.636358 [0002] <idle> 0.129 0.000 0.649
19818.636358 [0000] usleep[9117] 0.053 0.002 0.042
#
# perf sched timehist --time 19818.635696,19818.635709
Samples do not have callchains.
time cpu task name wait time sch delay run time
[tid/pid] (msec) (msec) (msec)
------------- ------ --------------- --------- --------- ---------
19818.635696 [0002] perf[9117] 0.000 0.120 0.000
19818.635702 [0000] <idle> 0.019 0.000 0.006
19818.635709 [0002] migration/2[25] 0.000 0.003 0.012
19818.635709 [0000] usleep[9117] 0.005 0.000 0.006
#
Signed-off-by: David Ahern <dsahern@gmail.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1480439746-42695-5-git-send-email-dsahern@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/Documentation/perf-sched.txt | 8 | ||||
-rw-r--r-- | tools/perf/builtin-sched.c | 51 |
2 files changed, 53 insertions, 6 deletions
diff --git a/tools/perf/Documentation/perf-sched.txt b/tools/perf/Documentation/perf-sched.txt index 121c60da03e5..7775b1eb2bee 100644 --- a/tools/perf/Documentation/perf-sched.txt +++ b/tools/perf/Documentation/perf-sched.txt | |||
@@ -132,6 +132,14 @@ OPTIONS for 'perf sched timehist' | |||
132 | --migrations:: | 132 | --migrations:: |
133 | Show migration events. | 133 | Show migration events. |
134 | 134 | ||
135 | --time:: | ||
136 | Only analyze samples within given time window: <start>,<stop>. Times | ||
137 | have the format seconds.microseconds. If start is not given (i.e., time | ||
138 | string is ',x.y') then analysis starts at the beginning of the file. If | ||
139 | stop time is not given (i.e, time string is 'x.y,') then analysis goes | ||
140 | to end of file. | ||
141 | |||
142 | |||
135 | SEE ALSO | 143 | SEE ALSO |
136 | -------- | 144 | -------- |
137 | linkperf:perf-record[1] | 145 | linkperf:perf-record[1] |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 4f9e7cba4ebf..870d94cd20ba 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "util/color.h" | 15 | #include "util/color.h" |
16 | #include "util/stat.h" | 16 | #include "util/stat.h" |
17 | #include "util/callchain.h" | 17 | #include "util/callchain.h" |
18 | #include "util/time-utils.h" | ||
18 | 19 | ||
19 | #include <subcmd/parse-options.h> | 20 | #include <subcmd/parse-options.h> |
20 | #include "util/trace-event.h" | 21 | #include "util/trace-event.h" |
@@ -205,6 +206,8 @@ struct perf_sched { | |||
205 | bool show_wakeups; | 206 | bool show_wakeups; |
206 | bool show_migrations; | 207 | bool show_migrations; |
207 | u64 skipped_samples; | 208 | u64 skipped_samples; |
209 | const char *time_str; | ||
210 | struct perf_time_interval ptime; | ||
208 | }; | 211 | }; |
209 | 212 | ||
210 | /* per thread run time data */ | 213 | /* per thread run time data */ |
@@ -1837,13 +1840,14 @@ static void timehist_header(struct perf_sched *sched) | |||
1837 | static void timehist_print_sample(struct perf_sched *sched, | 1840 | static void timehist_print_sample(struct perf_sched *sched, |
1838 | struct perf_sample *sample, | 1841 | struct perf_sample *sample, |
1839 | struct addr_location *al, | 1842 | struct addr_location *al, |
1840 | struct thread *thread) | 1843 | struct thread *thread, |
1844 | u64 t) | ||
1841 | { | 1845 | { |
1842 | struct thread_runtime *tr = thread__priv(thread); | 1846 | struct thread_runtime *tr = thread__priv(thread); |
1843 | u32 max_cpus = sched->max_cpu + 1; | 1847 | u32 max_cpus = sched->max_cpu + 1; |
1844 | char tstr[64]; | 1848 | char tstr[64]; |
1845 | 1849 | ||
1846 | timestamp__scnprintf_usec(sample->time, tstr, sizeof(tstr)); | 1850 | timestamp__scnprintf_usec(t, tstr, sizeof(tstr)); |
1847 | printf("%15s [%04d] ", tstr, sample->cpu); | 1851 | printf("%15s [%04d] ", tstr, sample->cpu); |
1848 | 1852 | ||
1849 | if (sched->show_cpu_visual) { | 1853 | if (sched->show_cpu_visual) { |
@@ -2194,7 +2198,8 @@ static int timehist_sched_wakeup_event(struct perf_tool *tool, | |||
2194 | tr->ready_to_run = sample->time; | 2198 | tr->ready_to_run = sample->time; |
2195 | 2199 | ||
2196 | /* show wakeups if requested */ | 2200 | /* show wakeups if requested */ |
2197 | if (sched->show_wakeups) | 2201 | if (sched->show_wakeups && |
2202 | !perf_time__skip_sample(&sched->ptime, sample->time)) | ||
2198 | timehist_print_wakeup_event(sched, sample, machine, thread); | 2203 | timehist_print_wakeup_event(sched, sample, machine, thread); |
2199 | 2204 | ||
2200 | return 0; | 2205 | return 0; |
@@ -2288,10 +2293,11 @@ static int timehist_sched_change_event(struct perf_tool *tool, | |||
2288 | struct machine *machine) | 2293 | struct machine *machine) |
2289 | { | 2294 | { |
2290 | struct perf_sched *sched = container_of(tool, struct perf_sched, tool); | 2295 | struct perf_sched *sched = container_of(tool, struct perf_sched, tool); |
2296 | struct perf_time_interval *ptime = &sched->ptime; | ||
2291 | struct addr_location al; | 2297 | struct addr_location al; |
2292 | struct thread *thread; | 2298 | struct thread *thread; |
2293 | struct thread_runtime *tr = NULL; | 2299 | struct thread_runtime *tr = NULL; |
2294 | u64 tprev; | 2300 | u64 tprev, t = sample->time; |
2295 | int rc = 0; | 2301 | int rc = 0; |
2296 | 2302 | ||
2297 | if (machine__resolve(machine, &al, sample) < 0) { | 2303 | if (machine__resolve(machine, &al, sample) < 0) { |
@@ -2318,9 +2324,35 @@ static int timehist_sched_change_event(struct perf_tool *tool, | |||
2318 | 2324 | ||
2319 | tprev = perf_evsel__get_time(evsel, sample->cpu); | 2325 | tprev = perf_evsel__get_time(evsel, sample->cpu); |
2320 | 2326 | ||
2321 | timehist_update_runtime_stats(tr, sample->time, tprev); | 2327 | /* |
2328 | * If start time given: | ||
2329 | * - sample time is under window user cares about - skip sample | ||
2330 | * - tprev is under window user cares about - reset to start of window | ||
2331 | */ | ||
2332 | if (ptime->start && ptime->start > t) | ||
2333 | goto out; | ||
2334 | |||
2335 | if (ptime->start > tprev) | ||
2336 | tprev = ptime->start; | ||
2337 | |||
2338 | /* | ||
2339 | * If end time given: | ||
2340 | * - previous sched event is out of window - we are done | ||
2341 | * - sample time is beyond window user cares about - reset it | ||
2342 | * to close out stats for time window interest | ||
2343 | */ | ||
2344 | if (ptime->end) { | ||
2345 | if (tprev > ptime->end) | ||
2346 | goto out; | ||
2347 | |||
2348 | if (t > ptime->end) | ||
2349 | t = ptime->end; | ||
2350 | } | ||
2351 | |||
2352 | timehist_update_runtime_stats(tr, t, tprev); | ||
2353 | |||
2322 | if (!sched->summary_only) | 2354 | if (!sched->summary_only) |
2323 | timehist_print_sample(sched, sample, &al, thread); | 2355 | timehist_print_sample(sched, sample, &al, thread, t); |
2324 | 2356 | ||
2325 | out: | 2357 | out: |
2326 | if (tr) { | 2358 | if (tr) { |
@@ -2583,6 +2615,11 @@ static int perf_sched__timehist(struct perf_sched *sched) | |||
2583 | 2615 | ||
2584 | symbol__init(&session->header.env); | 2616 | symbol__init(&session->header.env); |
2585 | 2617 | ||
2618 | if (perf_time__parse_str(&sched->ptime, sched->time_str) != 0) { | ||
2619 | pr_err("Invalid time string\n"); | ||
2620 | return -EINVAL; | ||
2621 | } | ||
2622 | |||
2586 | if (timehist_check_attr(sched, evlist) != 0) | 2623 | if (timehist_check_attr(sched, evlist) != 0) |
2587 | goto out; | 2624 | goto out; |
2588 | 2625 | ||
@@ -2997,6 +3034,8 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) | |||
2997 | OPT_BOOLEAN('w', "wakeups", &sched.show_wakeups, "Show wakeup events"), | 3034 | OPT_BOOLEAN('w', "wakeups", &sched.show_wakeups, "Show wakeup events"), |
2998 | OPT_BOOLEAN('M', "migrations", &sched.show_migrations, "Show migration events"), | 3035 | OPT_BOOLEAN('M', "migrations", &sched.show_migrations, "Show migration events"), |
2999 | OPT_BOOLEAN('V', "cpu-visual", &sched.show_cpu_visual, "Add CPU visual"), | 3036 | OPT_BOOLEAN('V', "cpu-visual", &sched.show_cpu_visual, "Add CPU visual"), |
3037 | OPT_STRING(0, "time", &sched.time_str, "str", | ||
3038 | "Time span for analysis (start,stop)"), | ||
3000 | OPT_PARENT(sched_options) | 3039 | OPT_PARENT(sched_options) |
3001 | }; | 3040 | }; |
3002 | 3041 | ||