Skip to content

Commit

Permalink
perf timechart: Add --highlight option
Browse files Browse the repository at this point in the history
This option highlights tasks (using different color) that run more than
given duration or tasks with given name.

Signed-off-by: Stanislav Fomichev <stfomichev@yandex-team.ru>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ramkumar Ramachandra <artagnon@gmail.com>
Link: http://lkml.kernel.org/r/20131217155349.GA13021@stfomichev-desktop
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Stanislav Fomichev authored and Arnaldo Carvalho de Melo committed Dec 17, 2013
1 parent ee4e962 commit e57a2df
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 5 deletions.
13 changes: 13 additions & 0 deletions tools/perf/Documentation/perf-timechart.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,25 @@ $ perf timechart

Written 10.2 seconds of trace to output.svg.

Record system-wide timechart:

$ perf timechart record

then generate timechart and highlight 'gcc' tasks:

$ perf timechart --highlight gcc

-n::
--proc-num::
Print task info for at least given number of tasks.
-t::
--topology::
Sort CPUs according to topology.
--highlight=<duration_nsecs|task_name>::
Highlight tasks (using different color) that run more than given
duration or tasks with given name. If number is given it's interpreted
as number of nanoseconds. If non-numeric string is given it's
interpreted as task name.

RECORD OPTIONS
--------------
Expand Down
21 changes: 20 additions & 1 deletion tools/perf/builtin-timechart.c
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,6 @@ static void draw_cpu_usage(struct timechart *tchart)
sample->start_time,
sample->end_time,
p->pid,
"sample",
c->comm,
sample->backtrace);
}
Expand Down Expand Up @@ -1252,6 +1251,23 @@ parse_process(const struct option *opt __maybe_unused, const char *arg,
return 0;
}

static int
parse_highlight(const struct option *opt __maybe_unused, const char *arg,
int __maybe_unused unset)
{
unsigned long duration = strtoul(arg, NULL, 0);

if (svg_highlight || svg_highlight_name)
return -1;

if (duration)
svg_highlight = duration;
else
svg_highlight_name = strdup(arg);

return 0;
}

int cmd_timechart(int argc, const char **argv,
const char *prefix __maybe_unused)
{
Expand All @@ -1270,6 +1286,9 @@ int cmd_timechart(int argc, const char **argv,
OPT_STRING('i', "input", &input_name, "file", "input file name"),
OPT_STRING('o', "output", &output_name, "file", "output file name"),
OPT_INTEGER('w', "width", &svg_page_width, "page width"),
OPT_CALLBACK(0, "highlight", NULL, "duration or task name",
"highlight tasks. Pass duration in ns or process name.",
parse_highlight),
OPT_BOOLEAN('P', "power-only", &tchart.power_only, "output power data only"),
OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only,
"output processes data only"),
Expand Down
23 changes: 20 additions & 3 deletions tools/perf/util/svghelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ static u64 turbo_frequency, max_freq;
#define SLOT_HEIGHT 25.0

int svg_page_width = 1000;
u64 svg_highlight;
const char *svg_highlight_name;

#define MIN_TEXT_SIZE 0.01

Expand Down Expand Up @@ -112,6 +114,7 @@ void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end)
fprintf(svgfile, " rect.process { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:1; stroke:rgb( 0, 0, 0); } \n");
fprintf(svgfile, " rect.process2 { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
fprintf(svgfile, " rect.sample { fill:rgb( 0, 0,255); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
fprintf(svgfile, " rect.sample_hi{ fill:rgb(255,128, 0); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
fprintf(svgfile, " rect.blocked { fill:rgb(255, 0, 0); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
fprintf(svgfile, " rect.waiting { fill:rgb(224,214, 0); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
fprintf(svgfile, " rect.WAITING { fill:rgb(255,214, 48); fill-opacity:0.6; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
Expand Down Expand Up @@ -155,17 +158,24 @@ void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
{
double text_size;
const char *type;

if (!svgfile)
return;

if (svg_highlight && end - start > svg_highlight)
type = "sample_hi";
else
type = "sample";
fprintf(svgfile, "<g>\n");

fprintf(svgfile, "<title>#%d running %s</title>\n",
cpu, time_to_string(end - start));
if (backtrace)
fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace);
fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"sample\"/>\n",
time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT);
fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"%s\"/>\n",
time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT,
type);

text_size = (time2pixels(end)-time2pixels(start));
if (cpu > 9)
Expand Down Expand Up @@ -293,13 +303,20 @@ void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
fprintf(svgfile, "</g>\n");
}

void svg_process(int cpu, u64 start, u64 end, int pid, const char *type, const char *name, const char *backtrace)
void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace)
{
double width;
const char *type;

if (!svgfile)
return;

if (svg_highlight && end - start >= svg_highlight)
type = "sample_hi";
else if (svg_highlight_name && strstr(name, svg_highlight_name))
type = "sample_hi";
else
type = "sample";

fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\">\n", time2pixels(start), cpu2y(cpu));
fprintf(svgfile, "<title>%d %s running %s</title>\n", pid, name, time_to_string(end - start));
Expand Down
4 changes: 3 additions & 1 deletion tools/perf/util/svghelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *back
extern void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency);


extern void svg_process(int cpu, u64 start, u64 end, int pid, const char *type, const char *name, const char *backtrace);
extern void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace);
extern void svg_cstate(int cpu, u64 start, u64 end, int type);
extern void svg_pstate(int cpu, u64 start, u64 end, u64 freq);

Expand All @@ -27,5 +27,7 @@ extern int svg_build_topology_map(char *sib_core, int sib_core_nr,
char *sib_thr, int sib_thr_nr);

extern int svg_page_width;
extern u64 svg_highlight;
extern const char *svg_highlight_name;

#endif /* __PERF_SVGHELPER_H */

0 comments on commit e57a2df

Please sign in to comment.