Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jiri Olsa and committed by
Arnaldo Carvalho de Melo
a151a37a 097be0f5

+76 -4
+3
tools/perf/Documentation/perf-sched.txt
··· 57 57 Show only CPUs with activity. Helps visualizing on high core 58 58 count systems. 59 59 60 + --color-pids:: 61 + Highlight the given pids. 62 + 60 63 SEE ALSO 61 64 -------- 62 65 linkperf:perf-record[1]
+73 -4
tools/perf/builtin-sched.c
··· 11 11 #include "util/session.h" 12 12 #include "util/tool.h" 13 13 #include "util/cloexec.h" 14 + #include "util/thread_map.h" 14 15 #include "util/color.h" 15 16 16 17 #include <subcmd/parse-options.h> ··· 124 123 struct machine *machine); 125 124 }; 126 125 126 + #define COLOR_PIDS PERF_COLOR_BLUE 127 + 127 128 struct perf_sched_map { 128 129 DECLARE_BITMAP(comp_cpus_mask, MAX_CPUS); 129 130 int *comp_cpus; 130 131 bool comp; 132 + struct thread_map *color_pids; 133 + const char *color_pids_str; 131 134 }; 132 135 133 136 struct perf_sched { ··· 1352 1347 return 0; 1353 1348 } 1354 1349 1350 + union map_priv { 1351 + void *ptr; 1352 + bool color; 1353 + }; 1354 + 1355 + static bool thread__has_color(struct thread *thread) 1356 + { 1357 + union map_priv priv = { 1358 + .ptr = thread__priv(thread), 1359 + }; 1360 + 1361 + return priv.color; 1362 + } 1363 + 1364 + static struct thread* 1365 + map__findnew_thread(struct perf_sched *sched, struct machine *machine, pid_t pid, pid_t tid) 1366 + { 1367 + struct thread *thread = machine__findnew_thread(machine, pid, tid); 1368 + union map_priv priv = { 1369 + .color = false, 1370 + }; 1371 + 1372 + if (!sched->map.color_pids || !thread || thread__priv(thread)) 1373 + return thread; 1374 + 1375 + if (thread_map__has(sched->map.color_pids, tid)) 1376 + priv.color = true; 1377 + 1378 + thread__set_priv(thread, priv.ptr); 1379 + return thread; 1380 + } 1381 + 1355 1382 static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, 1356 1383 struct perf_sample *sample, struct machine *machine) 1357 1384 { ··· 1423 1386 return -1; 1424 1387 } 1425 1388 1426 - sched_in = machine__findnew_thread(machine, -1, next_pid); 1389 + sched_in = map__findnew_thread(sched, machine, -1, next_pid); 1427 1390 if (sched_in == NULL) 1428 1391 return -1; 1429 1392 ··· 1459 1422 1460 1423 for (i = 0; i < cpus_nr; i++) { 1461 1424 int cpu = sched->map.comp ? sched->map.comp_cpus[i] : i; 1425 + struct thread *curr_thread = sched->curr_thread[cpu]; 1426 + const char *pid_color = color; 1427 + 1428 + if (curr_thread && thread__has_color(curr_thread)) 1429 + pid_color = COLOR_PIDS; 1462 1430 1463 1431 if (cpu != this_cpu) 1464 1432 color_fprintf(stdout, color, " "); ··· 1471 1429 color_fprintf(stdout, color, "*"); 1472 1430 1473 1431 if (sched->curr_thread[cpu]) 1474 - color_fprintf(stdout, color, "%2s ", sched->curr_thread[cpu]->shortname); 1432 + color_fprintf(stdout, pid_color, "%2s ", sched->curr_thread[cpu]->shortname); 1475 1433 else 1476 1434 color_fprintf(stdout, color, " "); 1477 1435 } 1478 1436 1479 1437 color_fprintf(stdout, color, " %12.6f secs ", (double)timestamp/1e9); 1480 1438 if (new_shortname) { 1481 - color_fprintf(stdout, color, "%s => %s:%d", 1439 + const char *pid_color = color; 1440 + 1441 + if (thread__has_color(sched_in)) 1442 + pid_color = COLOR_PIDS; 1443 + 1444 + color_fprintf(stdout, pid_color, "%s => %s:%d", 1482 1445 sched_in->shortname, thread__comm_str(sched_in), sched_in->tid); 1483 1446 } 1484 1447 ··· 1759 1712 return 0; 1760 1713 } 1761 1714 1715 + static int setup_color_pids(struct perf_sched *sched) 1716 + { 1717 + struct thread_map *map; 1718 + 1719 + if (!sched->map.color_pids_str) 1720 + return 0; 1721 + 1722 + map = thread_map__new_by_tid_str(sched->map.color_pids_str); 1723 + if (!map) { 1724 + pr_err("failed to get thread map from %s\n", sched->map.color_pids_str); 1725 + return -1; 1726 + } 1727 + 1728 + sched->map.color_pids = map; 1729 + return 0; 1730 + } 1731 + 1762 1732 static int perf_sched__map(struct perf_sched *sched) 1763 1733 { 1764 1734 if (setup_map_cpus(sched)) 1735 + return -1; 1736 + 1737 + if (setup_color_pids(sched)) 1765 1738 return -1; 1766 1739 1767 1740 setup_pager(); ··· 1939 1872 const struct option map_options[] = { 1940 1873 OPT_BOOLEAN(0, "compact", &sched.map.comp, 1941 1874 "map output in compact mode"), 1875 + OPT_STRING(0, "color-pids", &sched.map.color_pids_str, "pids", 1876 + "highlight given pids in map"), 1942 1877 OPT_END() 1943 1878 }; 1944 1879 const char * const latency_usage[] = { ··· 2004 1935 return perf_sched__lat(&sched); 2005 1936 } else if (!strcmp(argv[0], "map")) { 2006 1937 if (argc) { 2007 - argc = parse_options(argc, argv, map_options, replay_usage, 0); 1938 + argc = parse_options(argc, argv, map_options, map_usage, 0); 2008 1939 if (argc) 2009 1940 usage_with_options(map_usage, map_options); 2010 1941 }