Commit 99623c62 authored by Jiri Olsa's avatar Jiri Olsa Committed by Arnaldo Carvalho de Melo

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: default avatarJiri Olsa <jolsa@kernel.org>
Tested-by: default avatarArnaldo 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent e632aa69
...@@ -50,6 +50,13 @@ OPTIONS ...@@ -50,6 +50,13 @@ OPTIONS
--dump-raw-trace=:: --dump-raw-trace=::
Display verbose dump of the sched data. Display verbose dump of the sched data.
OPTIONS for 'perf sched map'
----------------------------
--compact::
Show only CPUs with activity. Helps visualizing on high core
count systems.
SEE ALSO SEE ALSO
-------- --------
linkperf:perf-record[1] linkperf:perf-record[1]
...@@ -122,6 +122,12 @@ struct trace_sched_handler { ...@@ -122,6 +122,12 @@ struct trace_sched_handler {
struct machine *machine); struct machine *machine);
}; };
struct perf_sched_map {
DECLARE_BITMAP(comp_cpus_mask, MAX_CPUS);
int *comp_cpus;
bool comp;
};
struct perf_sched { struct perf_sched {
struct perf_tool tool; struct perf_tool tool;
const char *sort_order; const char *sort_order;
...@@ -173,6 +179,7 @@ struct perf_sched { ...@@ -173,6 +179,7 @@ struct perf_sched {
struct list_head sort_list, cmp_pid; struct list_head sort_list, cmp_pid;
bool force; bool force;
bool skip_merge; bool skip_merge;
struct perf_sched_map map;
}; };
static u64 get_nsecs(void) static u64 get_nsecs(void)
...@@ -1347,13 +1354,24 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, ...@@ -1347,13 +1354,24 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
int new_shortname; int new_shortname;
u64 timestamp0, timestamp = sample->time; u64 timestamp0, timestamp = sample->time;
s64 delta; s64 delta;
int cpu, this_cpu = sample->cpu; int i, this_cpu = sample->cpu;
int cpus_nr;
bool new_cpu = false;
BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0); BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0);
if (this_cpu > sched->max_cpu) if (this_cpu > sched->max_cpu)
sched->max_cpu = this_cpu; sched->max_cpu = this_cpu;
if (sched->map.comp) {
cpus_nr = bitmap_weight(sched->map.comp_cpus_mask, MAX_CPUS);
if (!test_and_set_bit(this_cpu, sched->map.comp_cpus_mask)) {
sched->map.comp_cpus[cpus_nr++] = this_cpu;
new_cpu = true;
}
} else
cpus_nr = sched->max_cpu;
timestamp0 = sched->cpu_last_switched[this_cpu]; timestamp0 = sched->cpu_last_switched[this_cpu];
sched->cpu_last_switched[this_cpu] = timestamp; sched->cpu_last_switched[this_cpu] = timestamp;
if (timestamp0) if (timestamp0)
...@@ -1400,7 +1418,9 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, ...@@ -1400,7 +1418,9 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
new_shortname = 1; new_shortname = 1;
} }
for (cpu = 0; cpu <= sched->max_cpu; cpu++) { for (i = 0; i < cpus_nr; i++) {
int cpu = sched->map.comp ? sched->map.comp_cpus[i] : i;
if (cpu != this_cpu) if (cpu != this_cpu)
printf(" "); printf(" ");
else else
...@@ -1414,12 +1434,15 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, ...@@ -1414,12 +1434,15 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
printf(" %12.6f secs ", (double)timestamp/1e9); printf(" %12.6f secs ", (double)timestamp/1e9);
if (new_shortname) { if (new_shortname) {
printf("%s => %s:%d\n", printf("%s => %s:%d",
sched_in->shortname, thread__comm_str(sched_in), sched_in->tid); sched_in->shortname, thread__comm_str(sched_in), sched_in->tid);
} else {
printf("\n");
} }
if (sched->map.comp && new_cpu)
printf(" (CPU %d)", this_cpu);
printf("\n");
thread__put(sched_in); thread__put(sched_in);
return 0; return 0;
...@@ -1675,9 +1698,22 @@ static int perf_sched__lat(struct perf_sched *sched) ...@@ -1675,9 +1698,22 @@ static int perf_sched__lat(struct perf_sched *sched)
return 0; return 0;
} }
static int setup_map_cpus(struct perf_sched *sched)
{
sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF);
if (sched->map.comp) {
sched->map.comp_cpus = zalloc(sched->max_cpu * sizeof(int));
return sched->map.comp_cpus ? 0 : -1;
}
return 0;
}
static int perf_sched__map(struct perf_sched *sched) static int perf_sched__map(struct perf_sched *sched)
{ {
sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF); if (setup_map_cpus(sched))
return -1;
setup_pager(); setup_pager();
if (perf_sched__read_events(sched)) if (perf_sched__read_events(sched))
...@@ -1831,6 +1867,11 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1831,6 +1867,11 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
"dump raw trace in ASCII"), "dump raw trace in ASCII"),
OPT_END() OPT_END()
}; };
const struct option map_options[] = {
OPT_BOOLEAN(0, "compact", &sched.map.comp,
"map output in compact mode"),
OPT_END()
};
const char * const latency_usage[] = { const char * const latency_usage[] = {
"perf sched latency [<options>]", "perf sched latency [<options>]",
NULL NULL
...@@ -1839,6 +1880,10 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1839,6 +1880,10 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
"perf sched replay [<options>]", "perf sched replay [<options>]",
NULL NULL
}; };
const char * const map_usage[] = {
"perf sched map [<options>]",
NULL
};
const char *const sched_subcommands[] = { "record", "latency", "map", const char *const sched_subcommands[] = { "record", "latency", "map",
"replay", "script", NULL }; "replay", "script", NULL };
const char *sched_usage[] = { const char *sched_usage[] = {
...@@ -1887,6 +1932,11 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1887,6 +1932,11 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
setup_sorting(&sched, latency_options, latency_usage); setup_sorting(&sched, latency_options, latency_usage);
return perf_sched__lat(&sched); return perf_sched__lat(&sched);
} else if (!strcmp(argv[0], "map")) { } else if (!strcmp(argv[0], "map")) {
if (argc) {
argc = parse_options(argc, argv, map_options, replay_usage, 0);
if (argc)
usage_with_options(map_usage, map_options);
}
sched.tp_handler = &map_ops; sched.tp_handler = &map_ops;
setup_sorting(&sched, latency_options, latency_usage); setup_sorting(&sched, latency_options, latency_usage);
return perf_sched__map(&sched); return perf_sched__map(&sched);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment