diff options
author | Jiri Olsa <jolsa@kernel.org> | 2016-04-12 09:29:29 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-04-13 09:11:51 -0400 |
commit | a151a37a760aab41c115af8d5016e449228e8d2e (patch) | |
tree | 1d83faff8a7b4ba5c56392f80c25311ee1c6090e /tools | |
parent | 097be0f5034fc9edaf84253b773b14bc2af9a708 (diff) |
perf sched map: Color given pids
Adding --color-pids option to display selected pids in color (blue by
default). It helps on navigating through the 'perf sched map' output.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1460467771-26532-7-git-send-email-jolsa@kernel.org
[ Added entry to man page ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Documentation/perf-sched.txt | 3 | ||||
-rw-r--r-- | tools/perf/builtin-sched.c | 77 |
2 files changed, 76 insertions, 4 deletions
diff --git a/tools/perf/Documentation/perf-sched.txt b/tools/perf/Documentation/perf-sched.txt index 89b0c5b7fe84..67913de3aee7 100644 --- a/tools/perf/Documentation/perf-sched.txt +++ b/tools/perf/Documentation/perf-sched.txt | |||
@@ -57,6 +57,9 @@ OPTIONS for 'perf sched map' | |||
57 | Show only CPUs with activity. Helps visualizing on high core | 57 | Show only CPUs with activity. Helps visualizing on high core |
58 | count systems. | 58 | count systems. |
59 | 59 | ||
60 | --color-pids:: | ||
61 | Highlight the given pids. | ||
62 | |||
60 | SEE ALSO | 63 | SEE ALSO |
61 | -------- | 64 | -------- |
62 | linkperf:perf-record[1] | 65 | linkperf:perf-record[1] |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 9ef28973f198..b5361a1d20e1 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include "util/session.h" | 11 | #include "util/session.h" |
12 | #include "util/tool.h" | 12 | #include "util/tool.h" |
13 | #include "util/cloexec.h" | 13 | #include "util/cloexec.h" |
14 | #include "util/thread_map.h" | ||
14 | #include "util/color.h" | 15 | #include "util/color.h" |
15 | 16 | ||
16 | #include <subcmd/parse-options.h> | 17 | #include <subcmd/parse-options.h> |
@@ -123,10 +124,14 @@ struct trace_sched_handler { | |||
123 | struct machine *machine); | 124 | struct machine *machine); |
124 | }; | 125 | }; |
125 | 126 | ||
127 | #define COLOR_PIDS PERF_COLOR_BLUE | ||
128 | |||
126 | struct perf_sched_map { | 129 | struct perf_sched_map { |
127 | DECLARE_BITMAP(comp_cpus_mask, MAX_CPUS); | 130 | DECLARE_BITMAP(comp_cpus_mask, MAX_CPUS); |
128 | int *comp_cpus; | 131 | int *comp_cpus; |
129 | bool comp; | 132 | bool comp; |
133 | struct thread_map *color_pids; | ||
134 | const char *color_pids_str; | ||
130 | }; | 135 | }; |
131 | 136 | ||
132 | struct perf_sched { | 137 | struct perf_sched { |
@@ -1347,6 +1352,38 @@ static int process_sched_wakeup_event(struct perf_tool *tool, | |||
1347 | return 0; | 1352 | return 0; |
1348 | } | 1353 | } |
1349 | 1354 | ||
1355 | union map_priv { | ||
1356 | void *ptr; | ||
1357 | bool color; | ||
1358 | }; | ||
1359 | |||
1360 | static bool thread__has_color(struct thread *thread) | ||
1361 | { | ||
1362 | union map_priv priv = { | ||
1363 | .ptr = thread__priv(thread), | ||
1364 | }; | ||
1365 | |||
1366 | return priv.color; | ||
1367 | } | ||
1368 | |||
1369 | static struct thread* | ||
1370 | map__findnew_thread(struct perf_sched *sched, struct machine *machine, pid_t pid, pid_t tid) | ||
1371 | { | ||
1372 | struct thread *thread = machine__findnew_thread(machine, pid, tid); | ||
1373 | union map_priv priv = { | ||
1374 | .color = false, | ||
1375 | }; | ||
1376 | |||
1377 | if (!sched->map.color_pids || !thread || thread__priv(thread)) | ||
1378 | return thread; | ||
1379 | |||
1380 | if (thread_map__has(sched->map.color_pids, tid)) | ||
1381 | priv.color = true; | ||
1382 | |||
1383 | thread__set_priv(thread, priv.ptr); | ||
1384 | return thread; | ||
1385 | } | ||
1386 | |||
1350 | static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, | 1387 | static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, |
1351 | struct perf_sample *sample, struct machine *machine) | 1388 | struct perf_sample *sample, struct machine *machine) |
1352 | { | 1389 | { |
@@ -1386,7 +1423,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, | |||
1386 | return -1; | 1423 | return -1; |
1387 | } | 1424 | } |
1388 | 1425 | ||
1389 | sched_in = machine__findnew_thread(machine, -1, next_pid); | 1426 | sched_in = map__findnew_thread(sched, machine, -1, next_pid); |
1390 | if (sched_in == NULL) | 1427 | if (sched_in == NULL) |
1391 | return -1; | 1428 | return -1; |
1392 | 1429 | ||
@@ -1422,6 +1459,11 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, | |||
1422 | 1459 | ||
1423 | for (i = 0; i < cpus_nr; i++) { | 1460 | for (i = 0; i < cpus_nr; i++) { |
1424 | int cpu = sched->map.comp ? sched->map.comp_cpus[i] : i; | 1461 | int cpu = sched->map.comp ? sched->map.comp_cpus[i] : i; |
1462 | struct thread *curr_thread = sched->curr_thread[cpu]; | ||
1463 | const char *pid_color = color; | ||
1464 | |||
1465 | if (curr_thread && thread__has_color(curr_thread)) | ||
1466 | pid_color = COLOR_PIDS; | ||
1425 | 1467 | ||
1426 | if (cpu != this_cpu) | 1468 | if (cpu != this_cpu) |
1427 | color_fprintf(stdout, color, " "); | 1469 | color_fprintf(stdout, color, " "); |
@@ -1429,14 +1471,19 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, | |||
1429 | color_fprintf(stdout, color, "*"); | 1471 | color_fprintf(stdout, color, "*"); |
1430 | 1472 | ||
1431 | if (sched->curr_thread[cpu]) | 1473 | if (sched->curr_thread[cpu]) |
1432 | color_fprintf(stdout, color, "%2s ", sched->curr_thread[cpu]->shortname); | 1474 | color_fprintf(stdout, pid_color, "%2s ", sched->curr_thread[cpu]->shortname); |
1433 | else | 1475 | else |
1434 | color_fprintf(stdout, color, " "); | 1476 | color_fprintf(stdout, color, " "); |
1435 | } | 1477 | } |
1436 | 1478 | ||
1437 | color_fprintf(stdout, color, " %12.6f secs ", (double)timestamp/1e9); | 1479 | color_fprintf(stdout, color, " %12.6f secs ", (double)timestamp/1e9); |
1438 | if (new_shortname) { | 1480 | if (new_shortname) { |
1439 | color_fprintf(stdout, color, "%s => %s:%d", | 1481 | const char *pid_color = color; |
1482 | |||
1483 | if (thread__has_color(sched_in)) | ||
1484 | pid_color = COLOR_PIDS; | ||
1485 | |||
1486 | color_fprintf(stdout, pid_color, "%s => %s:%d", | ||
1440 | sched_in->shortname, thread__comm_str(sched_in), sched_in->tid); | 1487 | sched_in->shortname, thread__comm_str(sched_in), sched_in->tid); |
1441 | } | 1488 | } |
1442 | 1489 | ||
@@ -1712,11 +1759,31 @@ static int setup_map_cpus(struct perf_sched *sched) | |||
1712 | return 0; | 1759 | return 0; |
1713 | } | 1760 | } |
1714 | 1761 | ||
1762 | static int setup_color_pids(struct perf_sched *sched) | ||
1763 | { | ||
1764 | struct thread_map *map; | ||
1765 | |||
1766 | if (!sched->map.color_pids_str) | ||
1767 | return 0; | ||
1768 | |||
1769 | map = thread_map__new_by_tid_str(sched->map.color_pids_str); | ||
1770 | if (!map) { | ||
1771 | pr_err("failed to get thread map from %s\n", sched->map.color_pids_str); | ||
1772 | return -1; | ||
1773 | } | ||
1774 | |||
1775 | sched->map.color_pids = map; | ||
1776 | return 0; | ||
1777 | } | ||
1778 | |||
1715 | static int perf_sched__map(struct perf_sched *sched) | 1779 | static int perf_sched__map(struct perf_sched *sched) |
1716 | { | 1780 | { |
1717 | if (setup_map_cpus(sched)) | 1781 | if (setup_map_cpus(sched)) |
1718 | return -1; | 1782 | return -1; |
1719 | 1783 | ||
1784 | if (setup_color_pids(sched)) | ||
1785 | return -1; | ||
1786 | |||
1720 | setup_pager(); | 1787 | setup_pager(); |
1721 | if (perf_sched__read_events(sched)) | 1788 | if (perf_sched__read_events(sched)) |
1722 | return -1; | 1789 | return -1; |
@@ -1872,6 +1939,8 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1872 | const struct option map_options[] = { | 1939 | const struct option map_options[] = { |
1873 | OPT_BOOLEAN(0, "compact", &sched.map.comp, | 1940 | OPT_BOOLEAN(0, "compact", &sched.map.comp, |
1874 | "map output in compact mode"), | 1941 | "map output in compact mode"), |
1942 | OPT_STRING(0, "color-pids", &sched.map.color_pids_str, "pids", | ||
1943 | "highlight given pids in map"), | ||
1875 | OPT_END() | 1944 | OPT_END() |
1876 | }; | 1945 | }; |
1877 | const char * const latency_usage[] = { | 1946 | const char * const latency_usage[] = { |
@@ -1935,7 +2004,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1935 | return perf_sched__lat(&sched); | 2004 | return perf_sched__lat(&sched); |
1936 | } else if (!strcmp(argv[0], "map")) { | 2005 | } else if (!strcmp(argv[0], "map")) { |
1937 | if (argc) { | 2006 | if (argc) { |
1938 | argc = parse_options(argc, argv, map_options, replay_usage, 0); | 2007 | argc = parse_options(argc, argv, map_options, map_usage, 0); |
1939 | if (argc) | 2008 | if (argc) |
1940 | usage_with_options(map_usage, map_options); | 2009 | usage_with_options(map_usage, map_options); |
1941 | } | 2010 | } |