diff options
| author | Stanislav Fomichev <stfomichev@yandex-team.ru> | 2013-12-17 10:53:49 -0500 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-12-17 14:33:55 -0500 |
| commit | e57a2dffbc7e28cef5f4659b98a9d5595010ab4d (patch) | |
| tree | 4b09e46f5328e9f890002835179e09844d0ccbd7 /tools/perf | |
| parent | ee4e9625c8d4ec3a35322a882f7b6e035d2a1ad5 (diff) | |
perf timechart: Add --highlight option
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>
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/Documentation/perf-timechart.txt | 13 | ||||
| -rw-r--r-- | tools/perf/builtin-timechart.c | 21 | ||||
| -rw-r--r-- | tools/perf/util/svghelper.c | 23 | ||||
| -rw-r--r-- | tools/perf/util/svghelper.h | 4 |
4 files changed, 56 insertions, 5 deletions
diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt index 367c1be0551c..bc5990c33dc0 100644 --- a/tools/perf/Documentation/perf-timechart.txt +++ b/tools/perf/Documentation/perf-timechart.txt | |||
| @@ -56,12 +56,25 @@ $ perf timechart | |||
| 56 | 56 | ||
| 57 | Written 10.2 seconds of trace to output.svg. | 57 | Written 10.2 seconds of trace to output.svg. |
| 58 | 58 | ||
| 59 | Record system-wide timechart: | ||
| 60 | |||
| 61 | $ perf timechart record | ||
| 62 | |||
| 63 | then generate timechart and highlight 'gcc' tasks: | ||
| 64 | |||
| 65 | $ perf timechart --highlight gcc | ||
| 66 | |||
| 59 | -n:: | 67 | -n:: |
| 60 | --proc-num:: | 68 | --proc-num:: |
| 61 | Print task info for at least given number of tasks. | 69 | Print task info for at least given number of tasks. |
| 62 | -t:: | 70 | -t:: |
| 63 | --topology:: | 71 | --topology:: |
| 64 | Sort CPUs according to topology. | 72 | Sort CPUs according to topology. |
| 73 | --highlight=<duration_nsecs|task_name>:: | ||
| 74 | Highlight tasks (using different color) that run more than given | ||
| 75 | duration or tasks with given name. If number is given it's interpreted | ||
| 76 | as number of nanoseconds. If non-numeric string is given it's | ||
| 77 | interpreted as task name. | ||
| 65 | 78 | ||
| 66 | RECORD OPTIONS | 79 | RECORD OPTIONS |
| 67 | -------------- | 80 | -------------- |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 8bde57c5c908..20d4212fa337 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
| @@ -841,7 +841,6 @@ static void draw_cpu_usage(struct timechart *tchart) | |||
| 841 | sample->start_time, | 841 | sample->start_time, |
| 842 | sample->end_time, | 842 | sample->end_time, |
| 843 | p->pid, | 843 | p->pid, |
| 844 | "sample", | ||
| 845 | c->comm, | 844 | c->comm, |
| 846 | sample->backtrace); | 845 | sample->backtrace); |
| 847 | } | 846 | } |
| @@ -1252,6 +1251,23 @@ parse_process(const struct option *opt __maybe_unused, const char *arg, | |||
| 1252 | return 0; | 1251 | return 0; |
| 1253 | } | 1252 | } |
| 1254 | 1253 | ||
| 1254 | static int | ||
| 1255 | parse_highlight(const struct option *opt __maybe_unused, const char *arg, | ||
| 1256 | int __maybe_unused unset) | ||
| 1257 | { | ||
| 1258 | unsigned long duration = strtoul(arg, NULL, 0); | ||
| 1259 | |||
| 1260 | if (svg_highlight || svg_highlight_name) | ||
| 1261 | return -1; | ||
| 1262 | |||
| 1263 | if (duration) | ||
| 1264 | svg_highlight = duration; | ||
| 1265 | else | ||
| 1266 | svg_highlight_name = strdup(arg); | ||
| 1267 | |||
| 1268 | return 0; | ||
| 1269 | } | ||
| 1270 | |||
| 1255 | int cmd_timechart(int argc, const char **argv, | 1271 | int cmd_timechart(int argc, const char **argv, |
| 1256 | const char *prefix __maybe_unused) | 1272 | const char *prefix __maybe_unused) |
| 1257 | { | 1273 | { |
| @@ -1270,6 +1286,9 @@ int cmd_timechart(int argc, const char **argv, | |||
| 1270 | OPT_STRING('i', "input", &input_name, "file", "input file name"), | 1286 | OPT_STRING('i', "input", &input_name, "file", "input file name"), |
| 1271 | OPT_STRING('o', "output", &output_name, "file", "output file name"), | 1287 | OPT_STRING('o', "output", &output_name, "file", "output file name"), |
| 1272 | OPT_INTEGER('w', "width", &svg_page_width, "page width"), | 1288 | OPT_INTEGER('w', "width", &svg_page_width, "page width"), |
| 1289 | OPT_CALLBACK(0, "highlight", NULL, "duration or task name", | ||
| 1290 | "highlight tasks. Pass duration in ns or process name.", | ||
| 1291 | parse_highlight), | ||
| 1273 | OPT_BOOLEAN('P', "power-only", &tchart.power_only, "output power data only"), | 1292 | OPT_BOOLEAN('P', "power-only", &tchart.power_only, "output power data only"), |
| 1274 | OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only, | 1293 | OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only, |
| 1275 | "output processes data only"), | 1294 | "output processes data only"), |
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index 9468136735ca..56a84f2cc46d 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c | |||
| @@ -31,6 +31,8 @@ static u64 turbo_frequency, max_freq; | |||
| 31 | #define SLOT_HEIGHT 25.0 | 31 | #define SLOT_HEIGHT 25.0 |
| 32 | 32 | ||
| 33 | int svg_page_width = 1000; | 33 | int svg_page_width = 1000; |
| 34 | u64 svg_highlight; | ||
| 35 | const char *svg_highlight_name; | ||
| 34 | 36 | ||
| 35 | #define MIN_TEXT_SIZE 0.01 | 37 | #define MIN_TEXT_SIZE 0.01 |
| 36 | 38 | ||
| @@ -112,6 +114,7 @@ void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end) | |||
| 112 | fprintf(svgfile, " rect.process { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:1; stroke:rgb( 0, 0, 0); } \n"); | 114 | fprintf(svgfile, " rect.process { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:1; stroke:rgb( 0, 0, 0); } \n"); |
| 113 | fprintf(svgfile, " rect.process2 { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); | 115 | fprintf(svgfile, " rect.process2 { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); |
| 114 | fprintf(svgfile, " rect.sample { fill:rgb( 0, 0,255); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); | 116 | fprintf(svgfile, " rect.sample { fill:rgb( 0, 0,255); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); |
| 117 | fprintf(svgfile, " rect.sample_hi{ fill:rgb(255,128, 0); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); | ||
| 115 | fprintf(svgfile, " rect.blocked { fill:rgb(255, 0, 0); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); | 118 | fprintf(svgfile, " rect.blocked { fill:rgb(255, 0, 0); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); |
| 116 | fprintf(svgfile, " rect.waiting { fill:rgb(224,214, 0); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); | 119 | fprintf(svgfile, " rect.waiting { fill:rgb(224,214, 0); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); |
| 117 | fprintf(svgfile, " rect.WAITING { fill:rgb(255,214, 48); fill-opacity:0.6; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); | 120 | fprintf(svgfile, " rect.WAITING { fill:rgb(255,214, 48); fill-opacity:0.6; stroke-width:0; stroke:rgb( 0, 0, 0); } \n"); |
| @@ -155,17 +158,24 @@ void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace) | |||
| 155 | void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace) | 158 | void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace) |
| 156 | { | 159 | { |
| 157 | double text_size; | 160 | double text_size; |
| 161 | const char *type; | ||
| 162 | |||
| 158 | if (!svgfile) | 163 | if (!svgfile) |
| 159 | return; | 164 | return; |
| 160 | 165 | ||
| 166 | if (svg_highlight && end - start > svg_highlight) | ||
| 167 | type = "sample_hi"; | ||
| 168 | else | ||
| 169 | type = "sample"; | ||
| 161 | fprintf(svgfile, "<g>\n"); | 170 | fprintf(svgfile, "<g>\n"); |
| 162 | 171 | ||
| 163 | fprintf(svgfile, "<title>#%d running %s</title>\n", | 172 | fprintf(svgfile, "<title>#%d running %s</title>\n", |
| 164 | cpu, time_to_string(end - start)); | 173 | cpu, time_to_string(end - start)); |
| 165 | if (backtrace) | 174 | if (backtrace) |
| 166 | fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace); | 175 | fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace); |
| 167 | fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"sample\"/>\n", | 176 | fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"%s\"/>\n", |
| 168 | time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT); | 177 | time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT, |
| 178 | type); | ||
| 169 | 179 | ||
| 170 | text_size = (time2pixels(end)-time2pixels(start)); | 180 | text_size = (time2pixels(end)-time2pixels(start)); |
| 171 | if (cpu > 9) | 181 | if (cpu > 9) |
| @@ -293,13 +303,20 @@ void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq) | |||
| 293 | fprintf(svgfile, "</g>\n"); | 303 | fprintf(svgfile, "</g>\n"); |
| 294 | } | 304 | } |
| 295 | 305 | ||
| 296 | void svg_process(int cpu, u64 start, u64 end, int pid, const char *type, const char *name, const char *backtrace) | 306 | void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace) |
| 297 | { | 307 | { |
| 298 | double width; | 308 | double width; |
| 309 | const char *type; | ||
| 299 | 310 | ||
| 300 | if (!svgfile) | 311 | if (!svgfile) |
| 301 | return; | 312 | return; |
| 302 | 313 | ||
| 314 | if (svg_highlight && end - start >= svg_highlight) | ||
| 315 | type = "sample_hi"; | ||
| 316 | else if (svg_highlight_name && strstr(name, svg_highlight_name)) | ||
| 317 | type = "sample_hi"; | ||
| 318 | else | ||
| 319 | type = "sample"; | ||
| 303 | 320 | ||
| 304 | fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\">\n", time2pixels(start), cpu2y(cpu)); | 321 | fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\">\n", time2pixels(start), cpu2y(cpu)); |
| 305 | fprintf(svgfile, "<title>%d %s running %s</title>\n", pid, name, time_to_string(end - start)); | 322 | fprintf(svgfile, "<title>%d %s running %s</title>\n", pid, name, time_to_string(end - start)); |
diff --git a/tools/perf/util/svghelper.h b/tools/perf/util/svghelper.h index 1df4fb6c3a4a..f7b4d6e699ea 100644 --- a/tools/perf/util/svghelper.h +++ b/tools/perf/util/svghelper.h | |||
| @@ -11,7 +11,7 @@ extern void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *back | |||
| 11 | extern void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency); | 11 | extern void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency); |
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | extern void svg_process(int cpu, u64 start, u64 end, int pid, const char *type, const char *name, const char *backtrace); | 14 | extern void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace); |
| 15 | extern void svg_cstate(int cpu, u64 start, u64 end, int type); | 15 | extern void svg_cstate(int cpu, u64 start, u64 end, int type); |
| 16 | extern void svg_pstate(int cpu, u64 start, u64 end, u64 freq); | 16 | extern void svg_pstate(int cpu, u64 start, u64 end, u64 freq); |
| 17 | 17 | ||
| @@ -27,5 +27,7 @@ extern int svg_build_topology_map(char *sib_core, int sib_core_nr, | |||
| 27 | char *sib_thr, int sib_thr_nr); | 27 | char *sib_thr, int sib_thr_nr); |
| 28 | 28 | ||
| 29 | extern int svg_page_width; | 29 | extern int svg_page_width; |
| 30 | extern u64 svg_highlight; | ||
| 31 | extern const char *svg_highlight_name; | ||
| 30 | 32 | ||
| 31 | #endif /* __PERF_SVGHELPER_H */ | 33 | #endif /* __PERF_SVGHELPER_H */ |
