summaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-sched.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2016-04-12 09:29:26 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-04-13 09:11:51 -0400
commit99623c628f5425f09b5321cf621af1da29c0c47d (patch)
tree504170bab205d25e66b6b7d88ab4f0b38d65d184 /tools/perf/builtin-sched.c
parente632aa69c919462a7f93c8799b97c8a9ddd48fc2 (diff)
perf sched: Add compact display option
Add compact map display that does not output the whole cpu matrix, only cpus that got event. $ perf sched map --compact *A0 1082427.094098 secs A0 => perf:19404 (CPU 2) A0 *. 1082427.094127 secs . => swapper:0 (CPU 1) A0 . *B0 1082427.094174 secs B0 => rcuos/2:25 (CPU 3) A0 . *. 1082427.094177 secs *C0 . . 1082427.094187 secs C0 => migration/2:21 C0 *A0 . 1082427.094193 secs *. A0 . 1082427.094195 secs *D0 A0 . 1082427.094402 secs D0 => rngd:968 *. A0 . 1082427.094406 secs . *E0 . 1082427.095221 secs E0 => kworker/1:1:5333 . E0 *F0 1082427.095227 secs F0 => xterm:3342 It helps to display sane output for small thread loads on big cpu servers. 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-4-git-send-email-jolsa@kernel.org [ Add entry in 'perf sched' man page ] 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.c62
1 files changed, 56 insertions, 6 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 871b55ae22a4..64dd94667055 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -122,6 +122,12 @@ struct trace_sched_handler {
122 struct machine *machine); 122 struct machine *machine);
123}; 123};
124 124
125struct perf_sched_map {
126 DECLARE_BITMAP(comp_cpus_mask, MAX_CPUS);
127 int *comp_cpus;
128 bool comp;
129};
130
125struct perf_sched { 131struct perf_sched {
126 struct perf_tool tool; 132 struct perf_tool tool;
127 const char *sort_order; 133 const char *sort_order;
@@ -173,6 +179,7 @@ struct perf_sched {
173 struct list_head sort_list, cmp_pid; 179 struct list_head sort_list, cmp_pid;
174 bool force; 180 bool force;
175 bool skip_merge; 181 bool skip_merge;
182 struct perf_sched_map map;
176}; 183};
177 184
178static u64 get_nsecs(void) 185static u64 get_nsecs(void)
@@ -1347,13 +1354,24 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
1347 int new_shortname; 1354 int new_shortname;
1348 u64 timestamp0, timestamp = sample->time; 1355 u64 timestamp0, timestamp = sample->time;
1349 s64 delta; 1356 s64 delta;
1350 int cpu, this_cpu = sample->cpu; 1357 int i, this_cpu = sample->cpu;
1358 int cpus_nr;
1359 bool new_cpu = false;
1351 1360
1352 BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0); 1361 BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0);
1353 1362
1354 if (this_cpu > sched->max_cpu) 1363 if (this_cpu > sched->max_cpu)
1355 sched->max_cpu = this_cpu; 1364 sched->max_cpu = this_cpu;
1356 1365
1366 if (sched->map.comp) {
1367 cpus_nr = bitmap_weight(sched->map.comp_cpus_mask, MAX_CPUS);
1368 if (!test_and_set_bit(this_cpu, sched->map.comp_cpus_mask)) {
1369 sched->map.comp_cpus[cpus_nr++] = this_cpu;
1370 new_cpu = true;
1371 }
1372 } else
1373 cpus_nr = sched->max_cpu;
1374
1357 timestamp0 = sched->cpu_last_switched[this_cpu]; 1375 timestamp0 = sched->cpu_last_switched[this_cpu];
1358 sched->cpu_last_switched[this_cpu] = timestamp; 1376 sched->cpu_last_switched[this_cpu] = timestamp;
1359 if (timestamp0) 1377 if (timestamp0)
@@ -1400,7 +1418,9 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
1400 new_shortname = 1; 1418 new_shortname = 1;
1401 } 1419 }
1402 1420
1403 for (cpu = 0; cpu <= sched->max_cpu; cpu++) { 1421 for (i = 0; i < cpus_nr; i++) {
1422 int cpu = sched->map.comp ? sched->map.comp_cpus[i] : i;
1423
1404 if (cpu != this_cpu) 1424 if (cpu != this_cpu)
1405 printf(" "); 1425 printf(" ");
1406 else 1426 else
@@ -1414,12 +1434,15 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
1414 1434
1415 printf(" %12.6f secs ", (double)timestamp/1e9); 1435 printf(" %12.6f secs ", (double)timestamp/1e9);
1416 if (new_shortname) { 1436 if (new_shortname) {
1417 printf("%s => %s:%d\n", 1437 printf("%s => %s:%d",
1418 sched_in->shortname, thread__comm_str(sched_in), sched_in->tid); 1438 sched_in->shortname, thread__comm_str(sched_in), sched_in->tid);
1419 } else {
1420 printf("\n");
1421 } 1439 }
1422 1440
1441 if (sched->map.comp && new_cpu)
1442 printf(" (CPU %d)", this_cpu);
1443
1444 printf("\n");
1445
1423 thread__put(sched_in); 1446 thread__put(sched_in);
1424 1447
1425 return 0; 1448 return 0;
@@ -1675,9 +1698,22 @@ static int perf_sched__lat(struct perf_sched *sched)
1675 return 0; 1698 return 0;
1676} 1699}
1677 1700
1701static int setup_map_cpus(struct perf_sched *sched)
1702{
1703 sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF);
1704
1705 if (sched->map.comp) {
1706 sched->map.comp_cpus = zalloc(sched->max_cpu * sizeof(int));
1707 return sched->map.comp_cpus ? 0 : -1;
1708 }
1709
1710 return 0;
1711}
1712
1678static int perf_sched__map(struct perf_sched *sched) 1713static int perf_sched__map(struct perf_sched *sched)
1679{ 1714{
1680 sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF); 1715 if (setup_map_cpus(sched))
1716 return -1;
1681 1717
1682 setup_pager(); 1718 setup_pager();
1683 if (perf_sched__read_events(sched)) 1719 if (perf_sched__read_events(sched))
@@ -1831,6 +1867,11 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
1831 "dump raw trace in ASCII"), 1867 "dump raw trace in ASCII"),
1832 OPT_END() 1868 OPT_END()
1833 }; 1869 };
1870 const struct option map_options[] = {
1871 OPT_BOOLEAN(0, "compact", &sched.map.comp,
1872 "map output in compact mode"),
1873 OPT_END()
1874 };
1834 const char * const latency_usage[] = { 1875 const char * const latency_usage[] = {
1835 "perf sched latency [<options>]", 1876 "perf sched latency [<options>]",
1836 NULL 1877 NULL
@@ -1839,6 +1880,10 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
1839 "perf sched replay [<options>]", 1880 "perf sched replay [<options>]",
1840 NULL 1881 NULL
1841 }; 1882 };
1883 const char * const map_usage[] = {
1884 "perf sched map [<options>]",
1885 NULL
1886 };
1842 const char *const sched_subcommands[] = { "record", "latency", "map", 1887 const char *const sched_subcommands[] = { "record", "latency", "map",
1843 "replay", "script", NULL }; 1888 "replay", "script", NULL };
1844 const char *sched_usage[] = { 1889 const char *sched_usage[] = {
@@ -1887,6 +1932,11 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
1887 setup_sorting(&sched, latency_options, latency_usage); 1932 setup_sorting(&sched, latency_options, latency_usage);
1888 return perf_sched__lat(&sched); 1933 return perf_sched__lat(&sched);
1889 } else if (!strcmp(argv[0], "map")) { 1934 } else if (!strcmp(argv[0], "map")) {
1935 if (argc) {
1936 argc = parse_options(argc, argv, map_options, replay_usage, 0);
1937 if (argc)
1938 usage_with_options(map_usage, map_options);
1939 }
1890 sched.tp_handler = &map_ops; 1940 sched.tp_handler = &map_ops;
1891 setup_sorting(&sched, latency_options, latency_usage); 1941 setup_sorting(&sched, latency_options, latency_usage);
1892 return perf_sched__map(&sched); 1942 return perf_sched__map(&sched);