diff options
author | David Ahern <dsahern@gmail.com> | 2016-11-16 01:06:33 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-11-23 08:44:09 -0500 |
commit | a407b0678bc1c39d70af5fdbe6421c164b69a8c0 (patch) | |
tree | e4d9176d9f4abd6f2820bdcc0de1353c67d5797c /tools/perf/builtin-sched.c | |
parent | 6c973c90852c3fa4b4e76a061ce89dcd373efccc (diff) |
perf sched timehist: Add -V/--cpu-visual option
The -V option provides a visual aid for sched switches by cpu:
$ perf sched timehist -V
time cpu 0123456789abc task name b/n time sch delay run time
[tid/pid] (msec) (msec) (msec)
--------------- ------ ------------- -------------------- --------- --------- ---------
...
2412598.429696 [0009] i <idle> 0.000 0.000 0.000
2412598.429767 [0002] s perf[7219] 0.000 0.000 0.000
2412598.429783 [0009] s perf[7220] 0.000 0.006 0.087
2412598.429794 [0010] i <idle> 0.000 0.000 0.000
2412598.429795 [0009] s migration/9[53] 0.000 0.003 0.011
2412598.430370 [0010] s sleep[7220] 0.011 0.000 0.576
2412598.432584 [0003] i <idle> 0.000 0.000 0.000
...
Committer notes:
'i' marks idle time, 's' are scheduler events.
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/20161116060634.28477-8-namhyung@kernel.org
[ Add documentation based on above commit message ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-sched.c')
-rw-r--r-- | tools/perf/builtin-sched.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 1f8731640809..829468defa07 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -201,6 +201,7 @@ struct perf_sched { | |||
201 | bool summary_only; | 201 | bool summary_only; |
202 | bool show_callchain; | 202 | bool show_callchain; |
203 | unsigned int max_stack; | 203 | unsigned int max_stack; |
204 | bool show_cpu_visual; | ||
204 | bool show_wakeups; | 205 | bool show_wakeups; |
205 | u64 skipped_samples; | 206 | u64 skipped_samples; |
206 | }; | 207 | }; |
@@ -1783,10 +1784,23 @@ static char *timehist_get_commstr(struct thread *thread) | |||
1783 | return str; | 1784 | return str; |
1784 | } | 1785 | } |
1785 | 1786 | ||
1786 | static void timehist_header(void) | 1787 | static void timehist_header(struct perf_sched *sched) |
1787 | { | 1788 | { |
1789 | u32 ncpus = sched->max_cpu + 1; | ||
1790 | u32 i, j; | ||
1791 | |||
1788 | printf("%15s %6s ", "time", "cpu"); | 1792 | printf("%15s %6s ", "time", "cpu"); |
1789 | 1793 | ||
1794 | if (sched->show_cpu_visual) { | ||
1795 | printf(" "); | ||
1796 | for (i = 0, j = 0; i < ncpus; ++i) { | ||
1797 | printf("%x", j++); | ||
1798 | if (j > 15) | ||
1799 | j = 0; | ||
1800 | } | ||
1801 | printf(" "); | ||
1802 | } | ||
1803 | |||
1790 | printf(" %-20s %9s %9s %9s", | 1804 | printf(" %-20s %9s %9s %9s", |
1791 | "task name", "wait time", "sch delay", "run time"); | 1805 | "task name", "wait time", "sch delay", "run time"); |
1792 | 1806 | ||
@@ -1797,6 +1811,9 @@ static void timehist_header(void) | |||
1797 | */ | 1811 | */ |
1798 | printf("%15s %-6s ", "", ""); | 1812 | printf("%15s %-6s ", "", ""); |
1799 | 1813 | ||
1814 | if (sched->show_cpu_visual) | ||
1815 | printf(" %*s ", ncpus, ""); | ||
1816 | |||
1800 | printf(" %-20s %9s %9s %9s\n", "[tid/pid]", "(msec)", "(msec)", "(msec)"); | 1817 | printf(" %-20s %9s %9s %9s\n", "[tid/pid]", "(msec)", "(msec)", "(msec)"); |
1801 | 1818 | ||
1802 | /* | 1819 | /* |
@@ -1804,6 +1821,9 @@ static void timehist_header(void) | |||
1804 | */ | 1821 | */ |
1805 | printf("%.15s %.6s ", graph_dotted_line, graph_dotted_line); | 1822 | printf("%.15s %.6s ", graph_dotted_line, graph_dotted_line); |
1806 | 1823 | ||
1824 | if (sched->show_cpu_visual) | ||
1825 | printf(" %.*s ", ncpus, graph_dotted_line); | ||
1826 | |||
1807 | printf(" %.20s %.9s %.9s %.9s", | 1827 | printf(" %.20s %.9s %.9s %.9s", |
1808 | graph_dotted_line, graph_dotted_line, graph_dotted_line, | 1828 | graph_dotted_line, graph_dotted_line, graph_dotted_line, |
1809 | graph_dotted_line); | 1829 | graph_dotted_line); |
@@ -1817,11 +1837,28 @@ static void timehist_print_sample(struct perf_sched *sched, | |||
1817 | struct thread *thread) | 1837 | struct thread *thread) |
1818 | { | 1838 | { |
1819 | struct thread_runtime *tr = thread__priv(thread); | 1839 | struct thread_runtime *tr = thread__priv(thread); |
1840 | u32 max_cpus = sched->max_cpu + 1; | ||
1820 | char tstr[64]; | 1841 | char tstr[64]; |
1821 | 1842 | ||
1822 | timestamp__scnprintf_usec(sample->time, tstr, sizeof(tstr)); | 1843 | timestamp__scnprintf_usec(sample->time, tstr, sizeof(tstr)); |
1823 | printf("%15s [%04d] ", tstr, sample->cpu); | 1844 | printf("%15s [%04d] ", tstr, sample->cpu); |
1824 | 1845 | ||
1846 | if (sched->show_cpu_visual) { | ||
1847 | u32 i; | ||
1848 | char c; | ||
1849 | |||
1850 | printf(" "); | ||
1851 | for (i = 0; i < max_cpus; ++i) { | ||
1852 | /* flag idle times with 'i'; others are sched events */ | ||
1853 | if (i == sample->cpu) | ||
1854 | c = (thread->tid == 0) ? 'i' : 's'; | ||
1855 | else | ||
1856 | c = ' '; | ||
1857 | printf("%c", c); | ||
1858 | } | ||
1859 | printf(" "); | ||
1860 | } | ||
1861 | |||
1825 | printf(" %-*s ", comm_width, timehist_get_commstr(thread)); | 1862 | printf(" %-*s ", comm_width, timehist_get_commstr(thread)); |
1826 | 1863 | ||
1827 | print_sched_time(tr->dt_wait, 6); | 1864 | print_sched_time(tr->dt_wait, 6); |
@@ -2095,6 +2132,8 @@ static void timehist_print_wakeup_event(struct perf_sched *sched, | |||
2095 | 2132 | ||
2096 | timestamp__scnprintf_usec(sample->time, tstr, sizeof(tstr)); | 2133 | timestamp__scnprintf_usec(sample->time, tstr, sizeof(tstr)); |
2097 | printf("%15s [%04d] ", tstr, sample->cpu); | 2134 | printf("%15s [%04d] ", tstr, sample->cpu); |
2135 | if (sched->show_cpu_visual) | ||
2136 | printf(" %*s ", sched->max_cpu + 1, ""); | ||
2098 | 2137 | ||
2099 | printf(" %-*s ", comm_width, timehist_get_commstr(thread)); | 2138 | printf(" %-*s ", comm_width, timehist_get_commstr(thread)); |
2100 | 2139 | ||
@@ -2458,7 +2497,7 @@ static int perf_sched__timehist(struct perf_sched *sched) | |||
2458 | sched->summary = sched->summary_only; | 2497 | sched->summary = sched->summary_only; |
2459 | 2498 | ||
2460 | if (!sched->summary_only) | 2499 | if (!sched->summary_only) |
2461 | timehist_header(); | 2500 | timehist_header(sched); |
2462 | 2501 | ||
2463 | err = perf_session__process_events(session); | 2502 | err = perf_session__process_events(session); |
2464 | if (err) { | 2503 | if (err) { |
@@ -2842,6 +2881,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) | |||
2842 | OPT_BOOLEAN('S', "with-summary", &sched.summary, | 2881 | OPT_BOOLEAN('S', "with-summary", &sched.summary, |
2843 | "Show all syscalls and summary with statistics"), | 2882 | "Show all syscalls and summary with statistics"), |
2844 | OPT_BOOLEAN('w', "wakeups", &sched.show_wakeups, "Show wakeup events"), | 2883 | OPT_BOOLEAN('w', "wakeups", &sched.show_wakeups, "Show wakeup events"), |
2884 | OPT_BOOLEAN('V', "cpu-visual", &sched.show_cpu_visual, "Add CPU visual"), | ||
2845 | OPT_PARENT(sched_options) | 2885 | OPT_PARENT(sched_options) |
2846 | }; | 2886 | }; |
2847 | 2887 | ||