diff options
author | Ingo Molnar <mingo@kernel.org> | 2013-12-18 05:10:03 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-12-18 08:07:26 -0500 |
commit | fa6e8e5f7cbf85f364ebd5a90525dbbe9de2083b (patch) | |
tree | a85962bf1567292ac58f8340edc16f6cc35ea918 /tools/perf | |
parent | 9450d14fb959336803e5209119eb422b667b96aa (diff) | |
parent | f23b24f1bf90b56cfaeb2a1c9b77c46efe8916a6 (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and refactorings from Arnaldo Carvalho de Melo:
New features:
. In perf timechart:
- Add backtrace support to CPU info
. Print pid along the name
. Add support for CPU topology
. Add new option --highlight'ing threads, be it by name or,
if a numeric value is provided, that run more than given duration.
From Stanislav Fomichev.
Refactorings:
. Rename some struct DSO binary_type related members and methods,
to clarify its purpose and need for differentiation from symtab_type,
i.e. one is about the files .text, CFI, etc, i.e. its binary contents,
and the other is about where the symbol table came from.
. Convert to new topic libraries, starting with an API one (sysfs, debugfs,
etc), renaming liblk in the process, from Borislav Petkov.
. Get rid of some more panic() like error handling in libtraceevent,
from Namhyung Kim.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/Documentation/perf-timechart.txt | 16 | ||||
-rw-r--r-- | tools/perf/Makefile.perf | 33 | ||||
-rw-r--r-- | tools/perf/builtin-kvm.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-probe.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-timechart.c | 79 | ||||
-rw-r--r-- | tools/perf/perf.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/parse-events.c | 2 | ||||
-rw-r--r-- | tools/perf/util/dso.c | 24 | ||||
-rw-r--r-- | tools/perf/util/dso.h | 14 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 2 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 2 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 2 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 2 | ||||
-rw-r--r-- | tools/perf/util/setup.py | 4 | ||||
-rw-r--r-- | tools/perf/util/svghelper.c | 159 | ||||
-rw-r--r-- | tools/perf/util/svghelper.h | 6 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 12 | ||||
-rw-r--r-- | tools/perf/util/trace-event-info.c | 2 | ||||
-rw-r--r-- | tools/perf/util/util.h | 2 |
19 files changed, 297 insertions, 70 deletions
diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt index 271dd4ed5b05..bc5990c33dc0 100644 --- a/tools/perf/Documentation/perf-timechart.txt +++ b/tools/perf/Documentation/perf-timechart.txt | |||
@@ -56,9 +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. |
70 | -t:: | ||
71 | --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. | ||
62 | 78 | ||
63 | RECORD OPTIONS | 79 | RECORD OPTIONS |
64 | -------------- | 80 | -------------- |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index fad61079e795..97a2145e4cc6 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
@@ -86,7 +86,7 @@ FLEX = flex | |||
86 | BISON = bison | 86 | BISON = bison |
87 | STRIP = strip | 87 | STRIP = strip |
88 | 88 | ||
89 | LK_DIR = $(srctree)/tools/lib/lk/ | 89 | LIB_DIR = $(srctree)/tools/lib/api/ |
90 | TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ | 90 | TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ |
91 | 91 | ||
92 | # include config/Makefile by default and rule out | 92 | # include config/Makefile by default and rule out |
@@ -127,20 +127,20 @@ strip-libs = $(filter-out -l%,$(1)) | |||
127 | ifneq ($(OUTPUT),) | 127 | ifneq ($(OUTPUT),) |
128 | TE_PATH=$(OUTPUT) | 128 | TE_PATH=$(OUTPUT) |
129 | ifneq ($(subdir),) | 129 | ifneq ($(subdir),) |
130 | LK_PATH=$(OUTPUT)/../lib/lk/ | 130 | LIB_PATH=$(OUTPUT)/../lib/api/ |
131 | else | 131 | else |
132 | LK_PATH=$(OUTPUT) | 132 | LIB_PATH=$(OUTPUT) |
133 | endif | 133 | endif |
134 | else | 134 | else |
135 | TE_PATH=$(TRACE_EVENT_DIR) | 135 | TE_PATH=$(TRACE_EVENT_DIR) |
136 | LK_PATH=$(LK_DIR) | 136 | LIB_PATH=$(LIB_DIR) |
137 | endif | 137 | endif |
138 | 138 | ||
139 | LIBTRACEEVENT = $(TE_PATH)libtraceevent.a | 139 | LIBTRACEEVENT = $(TE_PATH)libtraceevent.a |
140 | export LIBTRACEEVENT | 140 | export LIBTRACEEVENT |
141 | 141 | ||
142 | LIBLK = $(LK_PATH)liblk.a | 142 | LIBAPIKFS = $(LIB_PATH)libapikfs.a |
143 | export LIBLK | 143 | export LIBAPIKFS |
144 | 144 | ||
145 | # python extension build directories | 145 | # python extension build directories |
146 | PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ | 146 | PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ |
@@ -151,7 +151,7 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP | |||
151 | python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so | 151 | python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so |
152 | 152 | ||
153 | PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) | 153 | PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) |
154 | PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBLK) | 154 | PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPIKFS) |
155 | 155 | ||
156 | $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) | 156 | $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) |
157 | $(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \ | 157 | $(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \ |
@@ -441,7 +441,7 @@ BUILTIN_OBJS += $(OUTPUT)builtin-inject.o | |||
441 | BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o | 441 | BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o |
442 | BUILTIN_OBJS += $(OUTPUT)builtin-mem.o | 442 | BUILTIN_OBJS += $(OUTPUT)builtin-mem.o |
443 | 443 | ||
444 | PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT) | 444 | PERFLIBS = $(LIB_FILE) $(LIBAPIKFS) $(LIBTRACEEVENT) |
445 | 445 | ||
446 | # We choose to avoid "if .. else if .. else .. endif endif" | 446 | # We choose to avoid "if .. else if .. else .. endif endif" |
447 | # because maintaining the nesting to match is a pain. If | 447 | # because maintaining the nesting to match is a pain. If |
@@ -730,19 +730,19 @@ $(LIBTRACEEVENT)-clean: | |||
730 | install-traceevent-plugins: $(LIBTRACEEVENT) | 730 | install-traceevent-plugins: $(LIBTRACEEVENT) |
731 | $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) install_plugins | 731 | $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) install_plugins |
732 | 732 | ||
733 | LIBLK_SOURCES = $(wildcard $(LK_PATH)*.[ch]) | 733 | LIBAPIKFS_SOURCES = $(wildcard $(LIB_PATH)fs/*.[ch]) |
734 | 734 | ||
735 | # if subdir is set, we've been called from above so target has been built | 735 | # if subdir is set, we've been called from above so target has been built |
736 | # already | 736 | # already |
737 | $(LIBLK): $(LIBLK_SOURCES) | 737 | $(LIBAPIKFS): $(LIBAPIKFS_SOURCES) |
738 | ifeq ($(subdir),) | 738 | ifeq ($(subdir),) |
739 | $(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) liblk.a | 739 | $(QUIET_SUBDIR0)$(LIB_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libapikfs.a |
740 | endif | 740 | endif |
741 | 741 | ||
742 | $(LIBLK)-clean: | 742 | $(LIBAPIKFS)-clean: |
743 | ifeq ($(subdir),) | 743 | ifeq ($(subdir),) |
744 | $(call QUIET_CLEAN, liblk) | 744 | $(call QUIET_CLEAN, libapikfs) |
745 | @$(MAKE) -C $(LK_DIR) O=$(OUTPUT) clean >/dev/null | 745 | @$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null |
746 | endif | 746 | endif |
747 | 747 | ||
748 | help: | 748 | help: |
@@ -881,12 +881,11 @@ config-clean: | |||
881 | $(call QUIET_CLEAN, config) | 881 | $(call QUIET_CLEAN, config) |
882 | @$(MAKE) -C config/feature-checks clean >/dev/null | 882 | @$(MAKE) -C config/feature-checks clean >/dev/null |
883 | 883 | ||
884 | clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-clean | 884 | clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean |
885 | $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) $(GTK_OBJS) | 885 | $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) $(GTK_OBJS) |
886 | $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf | 886 | $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf |
887 | $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* | 887 | $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* |
888 | $(call QUIET_CLEAN, Documentation) | 888 | $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean |
889 | @$(MAKE) -C Documentation O=$(OUTPUT) clean >/dev/null | ||
890 | $(python-clean) | 889 | $(python-clean) |
891 | 890 | ||
892 | # | 891 | # |
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index c6fa3cbd45a9..154b397a5d27 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include "util/parse-options.h" | 13 | #include "util/parse-options.h" |
14 | #include "util/trace-event.h" | 14 | #include "util/trace-event.h" |
15 | #include "util/debug.h" | 15 | #include "util/debug.h" |
16 | #include <lk/debugfs.h> | 16 | #include <api/fs/debugfs.h> |
17 | #include "util/tool.h" | 17 | #include "util/tool.h" |
18 | #include "util/stat.h" | 18 | #include "util/stat.h" |
19 | #include "util/top.h" | 19 | #include "util/top.h" |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 6ea9e85bdc00..c98ccb570509 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include "util/strfilter.h" | 37 | #include "util/strfilter.h" |
38 | #include "util/symbol.h" | 38 | #include "util/symbol.h" |
39 | #include "util/debug.h" | 39 | #include "util/debug.h" |
40 | #include <lk/debugfs.h> | 40 | #include <api/fs/debugfs.h> |
41 | #include "util/parse-options.h" | 41 | #include "util/parse-options.h" |
42 | #include "util/probe-finder.h" | 42 | #include "util/probe-finder.h" |
43 | #include "util/probe-event.h" | 43 | #include "util/probe-event.h" |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 0bda620a717d..20d4212fa337 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
@@ -58,7 +58,8 @@ struct timechart { | |||
58 | first_time, last_time; | 58 | first_time, last_time; |
59 | bool power_only, | 59 | bool power_only, |
60 | tasks_only, | 60 | tasks_only, |
61 | with_backtrace; | 61 | with_backtrace, |
62 | topology; | ||
62 | }; | 63 | }; |
63 | 64 | ||
64 | struct per_pidcomm; | 65 | struct per_pidcomm; |
@@ -531,12 +532,10 @@ static int process_sample_event(struct perf_tool *tool, | |||
531 | tchart->last_time = sample->time; | 532 | tchart->last_time = sample->time; |
532 | } | 533 | } |
533 | 534 | ||
534 | if (sample->cpu > tchart->numcpus) | ||
535 | tchart->numcpus = sample->cpu; | ||
536 | |||
537 | if (evsel->handler != NULL) { | 535 | if (evsel->handler != NULL) { |
538 | tracepoint_handler f = evsel->handler; | 536 | tracepoint_handler f = evsel->handler; |
539 | return f(tchart, evsel, sample, cat_backtrace(event, sample, machine)); | 537 | return f(tchart, evsel, sample, |
538 | cat_backtrace(event, sample, machine)); | ||
540 | } | 539 | } |
541 | 540 | ||
542 | return 0; | 541 | return 0; |
@@ -837,8 +836,14 @@ static void draw_cpu_usage(struct timechart *tchart) | |||
837 | while (c) { | 836 | while (c) { |
838 | sample = c->samples; | 837 | sample = c->samples; |
839 | while (sample) { | 838 | while (sample) { |
840 | if (sample->type == TYPE_RUNNING) | 839 | if (sample->type == TYPE_RUNNING) { |
841 | svg_process(sample->cpu, sample->start_time, sample->end_time, "sample", c->comm); | 840 | svg_process(sample->cpu, |
841 | sample->start_time, | ||
842 | sample->end_time, | ||
843 | p->pid, | ||
844 | c->comm, | ||
845 | sample->backtrace); | ||
846 | } | ||
842 | 847 | ||
843 | sample = sample->next; | 848 | sample = sample->next; |
844 | } | 849 | } |
@@ -1031,8 +1036,6 @@ static void write_svg_file(struct timechart *tchart, const char *filename) | |||
1031 | int count; | 1036 | int count; |
1032 | int thresh = TIME_THRESH; | 1037 | int thresh = TIME_THRESH; |
1033 | 1038 | ||
1034 | tchart->numcpus++; | ||
1035 | |||
1036 | if (tchart->power_only) | 1039 | if (tchart->power_only) |
1037 | tchart->proc_num = 0; | 1040 | tchart->proc_num = 0; |
1038 | 1041 | ||
@@ -1062,6 +1065,37 @@ static void write_svg_file(struct timechart *tchart, const char *filename) | |||
1062 | svg_close(); | 1065 | svg_close(); |
1063 | } | 1066 | } |
1064 | 1067 | ||
1068 | static int process_header(struct perf_file_section *section __maybe_unused, | ||
1069 | struct perf_header *ph, | ||
1070 | int feat, | ||
1071 | int fd __maybe_unused, | ||
1072 | void *data) | ||
1073 | { | ||
1074 | struct timechart *tchart = data; | ||
1075 | |||
1076 | switch (feat) { | ||
1077 | case HEADER_NRCPUS: | ||
1078 | tchart->numcpus = ph->env.nr_cpus_avail; | ||
1079 | break; | ||
1080 | |||
1081 | case HEADER_CPU_TOPOLOGY: | ||
1082 | if (!tchart->topology) | ||
1083 | break; | ||
1084 | |||
1085 | if (svg_build_topology_map(ph->env.sibling_cores, | ||
1086 | ph->env.nr_sibling_cores, | ||
1087 | ph->env.sibling_threads, | ||
1088 | ph->env.nr_sibling_threads)) | ||
1089 | fprintf(stderr, "problem building topology\n"); | ||
1090 | break; | ||
1091 | |||
1092 | default: | ||
1093 | break; | ||
1094 | } | ||
1095 | |||
1096 | return 0; | ||
1097 | } | ||
1098 | |||
1065 | static int __cmd_timechart(struct timechart *tchart, const char *output_name) | 1099 | static int __cmd_timechart(struct timechart *tchart, const char *output_name) |
1066 | { | 1100 | { |
1067 | const struct perf_evsel_str_handler power_tracepoints[] = { | 1101 | const struct perf_evsel_str_handler power_tracepoints[] = { |
@@ -1087,6 +1121,11 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) | |||
1087 | if (session == NULL) | 1121 | if (session == NULL) |
1088 | return -ENOMEM; | 1122 | return -ENOMEM; |
1089 | 1123 | ||
1124 | (void)perf_header__process_sections(&session->header, | ||
1125 | perf_data_file__fd(session->file), | ||
1126 | tchart, | ||
1127 | process_header); | ||
1128 | |||
1090 | if (!perf_session__has_traces(session, "timechart record")) | 1129 | if (!perf_session__has_traces(session, "timechart record")) |
1091 | goto out_delete; | 1130 | goto out_delete; |
1092 | 1131 | ||
@@ -1212,6 +1251,23 @@ parse_process(const struct option *opt __maybe_unused, const char *arg, | |||
1212 | return 0; | 1251 | return 0; |
1213 | } | 1252 | } |
1214 | 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 | |||
1215 | int cmd_timechart(int argc, const char **argv, | 1271 | int cmd_timechart(int argc, const char **argv, |
1216 | const char *prefix __maybe_unused) | 1272 | const char *prefix __maybe_unused) |
1217 | { | 1273 | { |
@@ -1230,6 +1286,9 @@ int cmd_timechart(int argc, const char **argv, | |||
1230 | OPT_STRING('i', "input", &input_name, "file", "input file name"), | 1286 | OPT_STRING('i', "input", &input_name, "file", "input file name"), |
1231 | OPT_STRING('o', "output", &output_name, "file", "output file name"), | 1287 | OPT_STRING('o', "output", &output_name, "file", "output file name"), |
1232 | 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), | ||
1233 | 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"), |
1234 | OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only, | 1293 | OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only, |
1235 | "output processes data only"), | 1294 | "output processes data only"), |
@@ -1240,6 +1299,8 @@ int cmd_timechart(int argc, const char **argv, | |||
1240 | "Look for files with symbols relative to this directory"), | 1299 | "Look for files with symbols relative to this directory"), |
1241 | OPT_INTEGER('n', "proc-num", &tchart.proc_num, | 1300 | OPT_INTEGER('n', "proc-num", &tchart.proc_num, |
1242 | "min. number of tasks to print"), | 1301 | "min. number of tasks to print"), |
1302 | OPT_BOOLEAN('t', "topology", &tchart.topology, | ||
1303 | "sort CPUs according to topology"), | ||
1243 | OPT_END() | 1304 | OPT_END() |
1244 | }; | 1305 | }; |
1245 | const char * const timechart_usage[] = { | 1306 | const char * const timechart_usage[] = { |
diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 8b38b4e80ec2..431798a4110d 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include "util/quote.h" | 13 | #include "util/quote.h" |
14 | #include "util/run-command.h" | 14 | #include "util/run-command.h" |
15 | #include "util/parse-events.h" | 15 | #include "util/parse-events.h" |
16 | #include <lk/debugfs.h> | 16 | #include <api/fs/debugfs.h> |
17 | #include <pthread.h> | 17 | #include <pthread.h> |
18 | 18 | ||
19 | const char perf_usage_string[] = | 19 | const char perf_usage_string[] = |
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 3cbd10496087..e4ce8aed29d3 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c | |||
@@ -3,7 +3,7 @@ | |||
3 | #include "evsel.h" | 3 | #include "evsel.h" |
4 | #include "evlist.h" | 4 | #include "evlist.h" |
5 | #include "fs.h" | 5 | #include "fs.h" |
6 | #include <lk/debugfs.h> | 6 | #include <api/fs/debugfs.h> |
7 | #include "tests.h" | 7 | #include "tests.h" |
8 | #include <linux/hw_breakpoint.h> | 8 | #include <linux/hw_breakpoint.h> |
9 | 9 | ||
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 436922f1f9d9..4ddeecb9ff85 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
@@ -28,8 +28,9 @@ char dso__symtab_origin(const struct dso *dso) | |||
28 | return origin[dso->symtab_type]; | 28 | return origin[dso->symtab_type]; |
29 | } | 29 | } |
30 | 30 | ||
31 | int dso__binary_type_file(const struct dso *dso, enum dso_binary_type type, | 31 | int dso__read_binary_type_filename(const struct dso *dso, |
32 | char *root_dir, char *filename, size_t size) | 32 | enum dso_binary_type type, |
33 | char *root_dir, char *filename, size_t size) | ||
33 | { | 34 | { |
34 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | 35 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; |
35 | int ret = 0; | 36 | int ret = 0; |
@@ -137,19 +138,18 @@ int dso__binary_type_file(const struct dso *dso, enum dso_binary_type type, | |||
137 | 138 | ||
138 | static int open_dso(struct dso *dso, struct machine *machine) | 139 | static int open_dso(struct dso *dso, struct machine *machine) |
139 | { | 140 | { |
140 | char *root_dir = (char *) ""; | ||
141 | char *name; | ||
142 | int fd; | 141 | int fd; |
142 | char *root_dir = (char *)""; | ||
143 | char *name = malloc(PATH_MAX); | ||
143 | 144 | ||
144 | name = malloc(PATH_MAX); | ||
145 | if (!name) | 145 | if (!name) |
146 | return -ENOMEM; | 146 | return -ENOMEM; |
147 | 147 | ||
148 | if (machine) | 148 | if (machine) |
149 | root_dir = machine->root_dir; | 149 | root_dir = machine->root_dir; |
150 | 150 | ||
151 | if (dso__binary_type_file(dso, dso->data_type, | 151 | if (dso__read_binary_type_filename(dso, dso->binary_type, |
152 | root_dir, name, PATH_MAX)) { | 152 | root_dir, name, PATH_MAX)) { |
153 | free(name); | 153 | free(name); |
154 | return -EINVAL; | 154 | return -EINVAL; |
155 | } | 155 | } |
@@ -161,26 +161,26 @@ static int open_dso(struct dso *dso, struct machine *machine) | |||
161 | 161 | ||
162 | int dso__data_fd(struct dso *dso, struct machine *machine) | 162 | int dso__data_fd(struct dso *dso, struct machine *machine) |
163 | { | 163 | { |
164 | static enum dso_binary_type binary_type_data[] = { | 164 | enum dso_binary_type binary_type_data[] = { |
165 | DSO_BINARY_TYPE__BUILD_ID_CACHE, | 165 | DSO_BINARY_TYPE__BUILD_ID_CACHE, |
166 | DSO_BINARY_TYPE__SYSTEM_PATH_DSO, | 166 | DSO_BINARY_TYPE__SYSTEM_PATH_DSO, |
167 | DSO_BINARY_TYPE__NOT_FOUND, | 167 | DSO_BINARY_TYPE__NOT_FOUND, |
168 | }; | 168 | }; |
169 | int i = 0; | 169 | int i = 0; |
170 | 170 | ||
171 | if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND) | 171 | if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND) |
172 | return open_dso(dso, machine); | 172 | return open_dso(dso, machine); |
173 | 173 | ||
174 | do { | 174 | do { |
175 | int fd; | 175 | int fd; |
176 | 176 | ||
177 | dso->data_type = binary_type_data[i++]; | 177 | dso->binary_type = binary_type_data[i++]; |
178 | 178 | ||
179 | fd = open_dso(dso, machine); | 179 | fd = open_dso(dso, machine); |
180 | if (fd >= 0) | 180 | if (fd >= 0) |
181 | return fd; | 181 | return fd; |
182 | 182 | ||
183 | } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND); | 183 | } while (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND); |
184 | 184 | ||
185 | return -EINVAL; | 185 | return -EINVAL; |
186 | } | 186 | } |
@@ -475,7 +475,7 @@ struct dso *dso__new(const char *name) | |||
475 | dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; | 475 | dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; |
476 | dso->cache = RB_ROOT; | 476 | dso->cache = RB_ROOT; |
477 | dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND; | 477 | dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND; |
478 | dso->data_type = DSO_BINARY_TYPE__NOT_FOUND; | 478 | dso->binary_type = DSO_BINARY_TYPE__NOT_FOUND; |
479 | dso->loaded = 0; | 479 | dso->loaded = 0; |
480 | dso->rel = 0; | 480 | dso->rel = 0; |
481 | dso->sorted_by_name = 0; | 481 | dso->sorted_by_name = 0; |
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index e1cc50698137..cd7d6f078cdd 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h | |||
@@ -83,7 +83,7 @@ struct dso { | |||
83 | enum dso_kernel_type kernel; | 83 | enum dso_kernel_type kernel; |
84 | enum dso_swap_type needs_swap; | 84 | enum dso_swap_type needs_swap; |
85 | enum dso_binary_type symtab_type; | 85 | enum dso_binary_type symtab_type; |
86 | enum dso_binary_type data_type; | 86 | enum dso_binary_type binary_type; |
87 | u8 adjust_symbols:1; | 87 | u8 adjust_symbols:1; |
88 | u8 has_build_id:1; | 88 | u8 has_build_id:1; |
89 | u8 has_srcline:1; | 89 | u8 has_srcline:1; |
@@ -128,8 +128,8 @@ void dso__read_running_kernel_build_id(struct dso *dso, | |||
128 | int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir); | 128 | int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir); |
129 | 129 | ||
130 | char dso__symtab_origin(const struct dso *dso); | 130 | char dso__symtab_origin(const struct dso *dso); |
131 | int dso__binary_type_file(const struct dso *dso, enum dso_binary_type type, | 131 | int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type, |
132 | char *root_dir, char *filename, size_t size); | 132 | char *root_dir, char *filename, size_t size); |
133 | 133 | ||
134 | int dso__data_fd(struct dso *dso, struct machine *machine); | 134 | int dso__data_fd(struct dso *dso, struct machine *machine); |
135 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | 135 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, |
@@ -159,14 +159,14 @@ size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp); | |||
159 | 159 | ||
160 | static inline bool dso__is_vmlinux(struct dso *dso) | 160 | static inline bool dso__is_vmlinux(struct dso *dso) |
161 | { | 161 | { |
162 | return dso->data_type == DSO_BINARY_TYPE__VMLINUX || | 162 | return dso->binary_type == DSO_BINARY_TYPE__VMLINUX || |
163 | dso->data_type == DSO_BINARY_TYPE__GUEST_VMLINUX; | 163 | dso->binary_type == DSO_BINARY_TYPE__GUEST_VMLINUX; |
164 | } | 164 | } |
165 | 165 | ||
166 | static inline bool dso__is_kcore(struct dso *dso) | 166 | static inline bool dso__is_kcore(struct dso *dso) |
167 | { | 167 | { |
168 | return dso->data_type == DSO_BINARY_TYPE__KCORE || | 168 | return dso->binary_type == DSO_BINARY_TYPE__KCORE || |
169 | dso->data_type == DSO_BINARY_TYPE__GUEST_KCORE; | 169 | dso->binary_type == DSO_BINARY_TYPE__GUEST_KCORE; |
170 | } | 170 | } |
171 | 171 | ||
172 | void dso__free_a2l(struct dso *dso); | 172 | void dso__free_a2l(struct dso *dso); |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 0b31cee34874..da3182914984 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Released under the GPL v2. (and only v2, not any later version) | 7 | * Released under the GPL v2. (and only v2, not any later version) |
8 | */ | 8 | */ |
9 | #include "util.h" | 9 | #include "util.h" |
10 | #include <lk/debugfs.h> | 10 | #include <api/fs/debugfs.h> |
11 | #include <poll.h> | 11 | #include <poll.h> |
12 | #include "cpumap.h" | 12 | #include "cpumap.h" |
13 | #include "thread_map.h" | 13 | #include "thread_map.h" |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 7b510fd1f08d..01ff4cfde1f5 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | #include <byteswap.h> | 10 | #include <byteswap.h> |
11 | #include <linux/bitops.h> | 11 | #include <linux/bitops.h> |
12 | #include <lk/debugfs.h> | 12 | #include <api/fs/debugfs.h> |
13 | #include <traceevent/event-parse.h> | 13 | #include <traceevent/event-parse.h> |
14 | #include <linux/hw_breakpoint.h> | 14 | #include <linux/hw_breakpoint.h> |
15 | #include <linux/perf_event.h> | 15 | #include <linux/perf_event.h> |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 969cb8f0d88d..094c28ba2fae 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "symbol.h" | 10 | #include "symbol.h" |
11 | #include "cache.h" | 11 | #include "cache.h" |
12 | #include "header.h" | 12 | #include "header.h" |
13 | #include <lk/debugfs.h> | 13 | #include <api/fs/debugfs.h> |
14 | #include "parse-events-bison.h" | 14 | #include "parse-events-bison.h" |
15 | #define YY_EXTRA_TYPE int | 15 | #define YY_EXTRA_TYPE int |
16 | #include "parse-events-flex.h" | 16 | #include "parse-events-flex.h" |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index d7cff57945c2..544ac1898a9f 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include "color.h" | 40 | #include "color.h" |
41 | #include "symbol.h" | 41 | #include "symbol.h" |
42 | #include "thread.h" | 42 | #include "thread.h" |
43 | #include <lk/debugfs.h> | 43 | #include <api/fs/debugfs.h> |
44 | #include "trace-event.h" /* For __maybe_unused */ | 44 | #include "trace-event.h" /* For __maybe_unused */ |
45 | #include "probe-event.h" | 45 | #include "probe-event.h" |
46 | #include "probe-finder.h" | 46 | #include "probe-finder.h" |
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index 58ea5ca6c255..d0aee4b9dfd4 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py | |||
@@ -25,7 +25,7 @@ cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' | |||
25 | build_lib = getenv('PYTHON_EXTBUILD_LIB') | 25 | build_lib = getenv('PYTHON_EXTBUILD_LIB') |
26 | build_tmp = getenv('PYTHON_EXTBUILD_TMP') | 26 | build_tmp = getenv('PYTHON_EXTBUILD_TMP') |
27 | libtraceevent = getenv('LIBTRACEEVENT') | 27 | libtraceevent = getenv('LIBTRACEEVENT') |
28 | liblk = getenv('LIBLK') | 28 | libapikfs = getenv('LIBAPIKFS') |
29 | 29 | ||
30 | ext_sources = [f.strip() for f in file('util/python-ext-sources') | 30 | ext_sources = [f.strip() for f in file('util/python-ext-sources') |
31 | if len(f.strip()) > 0 and f[0] != '#'] | 31 | if len(f.strip()) > 0 and f[0] != '#'] |
@@ -34,7 +34,7 @@ perf = Extension('perf', | |||
34 | sources = ext_sources, | 34 | sources = ext_sources, |
35 | include_dirs = ['util/include'], | 35 | include_dirs = ['util/include'], |
36 | extra_compile_args = cflags, | 36 | extra_compile_args = cflags, |
37 | extra_objects = [libtraceevent, liblk], | 37 | extra_objects = [libtraceevent, libapikfs], |
38 | ) | 38 | ) |
39 | 39 | ||
40 | setup(name='perf', | 40 | setup(name='perf', |
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index 8b79d3ad1246..56a84f2cc46d 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c | |||
@@ -17,8 +17,11 @@ | |||
17 | #include <stdlib.h> | 17 | #include <stdlib.h> |
18 | #include <unistd.h> | 18 | #include <unistd.h> |
19 | #include <string.h> | 19 | #include <string.h> |
20 | #include <linux/bitops.h> | ||
20 | 21 | ||
22 | #include "perf.h" | ||
21 | #include "svghelper.h" | 23 | #include "svghelper.h" |
24 | #include "cpumap.h" | ||
22 | 25 | ||
23 | static u64 first_time, last_time; | 26 | static u64 first_time, last_time; |
24 | static u64 turbo_frequency, max_freq; | 27 | static u64 turbo_frequency, max_freq; |
@@ -28,6 +31,8 @@ static u64 turbo_frequency, max_freq; | |||
28 | #define SLOT_HEIGHT 25.0 | 31 | #define SLOT_HEIGHT 25.0 |
29 | 32 | ||
30 | int svg_page_width = 1000; | 33 | int svg_page_width = 1000; |
34 | u64 svg_highlight; | ||
35 | const char *svg_highlight_name; | ||
31 | 36 | ||
32 | #define MIN_TEXT_SIZE 0.01 | 37 | #define MIN_TEXT_SIZE 0.01 |
33 | 38 | ||
@@ -39,9 +44,14 @@ static double cpu2slot(int cpu) | |||
39 | return 2 * cpu + 1; | 44 | return 2 * cpu + 1; |
40 | } | 45 | } |
41 | 46 | ||
47 | static int *topology_map; | ||
48 | |||
42 | static double cpu2y(int cpu) | 49 | static double cpu2y(int cpu) |
43 | { | 50 | { |
44 | return cpu2slot(cpu) * SLOT_MULT; | 51 | if (topology_map) |
52 | return cpu2slot(topology_map[cpu]) * SLOT_MULT; | ||
53 | else | ||
54 | return cpu2slot(cpu) * SLOT_MULT; | ||
45 | } | 55 | } |
46 | 56 | ||
47 | static double time2pixels(u64 __time) | 57 | static double time2pixels(u64 __time) |
@@ -104,6 +114,7 @@ void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end) | |||
104 | 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"); |
105 | 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"); |
106 | 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"); | ||
107 | 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"); |
108 | 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"); |
109 | 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"); |
@@ -147,17 +158,24 @@ void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace) | |||
147 | 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) |
148 | { | 159 | { |
149 | double text_size; | 160 | double text_size; |
161 | const char *type; | ||
162 | |||
150 | if (!svgfile) | 163 | if (!svgfile) |
151 | return; | 164 | return; |
152 | 165 | ||
166 | if (svg_highlight && end - start > svg_highlight) | ||
167 | type = "sample_hi"; | ||
168 | else | ||
169 | type = "sample"; | ||
153 | fprintf(svgfile, "<g>\n"); | 170 | fprintf(svgfile, "<g>\n"); |
154 | 171 | ||
155 | fprintf(svgfile, "<title>#%d running %s</title>\n", | 172 | fprintf(svgfile, "<title>#%d running %s</title>\n", |
156 | cpu, time_to_string(end - start)); | 173 | cpu, time_to_string(end - start)); |
157 | if (backtrace) | 174 | if (backtrace) |
158 | fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace); | 175 | fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace); |
159 | 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", |
160 | 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); | ||
161 | 179 | ||
162 | text_size = (time2pixels(end)-time2pixels(start)); | 180 | text_size = (time2pixels(end)-time2pixels(start)); |
163 | if (cpu > 9) | 181 | if (cpu > 9) |
@@ -275,7 +293,7 @@ void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq) | |||
275 | time2pixels(last_time)-time2pixels(first_time), | 293 | time2pixels(last_time)-time2pixels(first_time), |
276 | cpu2y(cpu), SLOT_MULT+SLOT_HEIGHT); | 294 | cpu2y(cpu), SLOT_MULT+SLOT_HEIGHT); |
277 | 295 | ||
278 | sprintf(cpu_string, "CPU %i", (int)cpu+1); | 296 | sprintf(cpu_string, "CPU %i", (int)cpu); |
279 | fprintf(svgfile, "<text x=\"%4.8f\" y=\"%4.8f\">%s</text>\n", | 297 | fprintf(svgfile, "<text x=\"%4.8f\" y=\"%4.8f\">%s</text>\n", |
280 | 10+time2pixels(first_time), cpu2y(cpu) + SLOT_HEIGHT/2, cpu_string); | 298 | 10+time2pixels(first_time), cpu2y(cpu) + SLOT_HEIGHT/2, cpu_string); |
281 | 299 | ||
@@ -285,16 +303,25 @@ void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq) | |||
285 | fprintf(svgfile, "</g>\n"); | 303 | fprintf(svgfile, "</g>\n"); |
286 | } | 304 | } |
287 | 305 | ||
288 | void svg_process(int cpu, u64 start, u64 end, const char *type, const char *name) | 306 | void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace) |
289 | { | 307 | { |
290 | double width; | 308 | double width; |
309 | const char *type; | ||
291 | 310 | ||
292 | if (!svgfile) | 311 | if (!svgfile) |
293 | return; | 312 | return; |
294 | 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"; | ||
295 | 320 | ||
296 | 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)); |
297 | fprintf(svgfile, "<title>%s %s</title>\n", name, time_to_string(end - start)); | 322 | fprintf(svgfile, "<title>%d %s running %s</title>\n", pid, name, time_to_string(end - start)); |
323 | if (backtrace) | ||
324 | fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace); | ||
298 | fprintf(svgfile, "<rect x=\"0\" width=\"%4.8f\" y=\"0\" height=\"%4.1f\" class=\"%s\"/>\n", | 325 | fprintf(svgfile, "<rect x=\"0\" width=\"%4.8f\" y=\"0\" height=\"%4.1f\" class=\"%s\"/>\n", |
299 | time2pixels(end)-time2pixels(start), SLOT_MULT+SLOT_HEIGHT, type); | 326 | time2pixels(end)-time2pixels(start), SLOT_MULT+SLOT_HEIGHT, type); |
300 | width = time2pixels(end)-time2pixels(start); | 327 | width = time2pixels(end)-time2pixels(start); |
@@ -566,3 +593,123 @@ void svg_close(void) | |||
566 | svgfile = NULL; | 593 | svgfile = NULL; |
567 | } | 594 | } |
568 | } | 595 | } |
596 | |||
597 | #define cpumask_bits(maskp) ((maskp)->bits) | ||
598 | typedef struct { DECLARE_BITMAP(bits, MAX_NR_CPUS); } cpumask_t; | ||
599 | |||
600 | struct topology { | ||
601 | cpumask_t *sib_core; | ||
602 | int sib_core_nr; | ||
603 | cpumask_t *sib_thr; | ||
604 | int sib_thr_nr; | ||
605 | }; | ||
606 | |||
607 | static void scan_thread_topology(int *map, struct topology *t, int cpu, int *pos) | ||
608 | { | ||
609 | int i; | ||
610 | int thr; | ||
611 | |||
612 | for (i = 0; i < t->sib_thr_nr; i++) { | ||
613 | if (!test_bit(cpu, cpumask_bits(&t->sib_thr[i]))) | ||
614 | continue; | ||
615 | |||
616 | for_each_set_bit(thr, | ||
617 | cpumask_bits(&t->sib_thr[i]), | ||
618 | MAX_NR_CPUS) | ||
619 | if (map[thr] == -1) | ||
620 | map[thr] = (*pos)++; | ||
621 | } | ||
622 | } | ||
623 | |||
624 | static void scan_core_topology(int *map, struct topology *t) | ||
625 | { | ||
626 | int pos = 0; | ||
627 | int i; | ||
628 | int cpu; | ||
629 | |||
630 | for (i = 0; i < t->sib_core_nr; i++) | ||
631 | for_each_set_bit(cpu, | ||
632 | cpumask_bits(&t->sib_core[i]), | ||
633 | MAX_NR_CPUS) | ||
634 | scan_thread_topology(map, t, cpu, &pos); | ||
635 | } | ||
636 | |||
637 | static int str_to_bitmap(char *s, cpumask_t *b) | ||
638 | { | ||
639 | int i; | ||
640 | int ret = 0; | ||
641 | struct cpu_map *m; | ||
642 | int c; | ||
643 | |||
644 | m = cpu_map__new(s); | ||
645 | if (!m) | ||
646 | return -1; | ||
647 | |||
648 | for (i = 0; i < m->nr; i++) { | ||
649 | c = m->map[i]; | ||
650 | if (c >= MAX_NR_CPUS) { | ||
651 | ret = -1; | ||
652 | break; | ||
653 | } | ||
654 | |||
655 | set_bit(c, cpumask_bits(b)); | ||
656 | } | ||
657 | |||
658 | cpu_map__delete(m); | ||
659 | |||
660 | return ret; | ||
661 | } | ||
662 | |||
663 | int svg_build_topology_map(char *sib_core, int sib_core_nr, | ||
664 | char *sib_thr, int sib_thr_nr) | ||
665 | { | ||
666 | int i; | ||
667 | struct topology t; | ||
668 | |||
669 | t.sib_core_nr = sib_core_nr; | ||
670 | t.sib_thr_nr = sib_thr_nr; | ||
671 | t.sib_core = calloc(sib_core_nr, sizeof(cpumask_t)); | ||
672 | t.sib_thr = calloc(sib_thr_nr, sizeof(cpumask_t)); | ||
673 | |||
674 | if (!t.sib_core || !t.sib_thr) { | ||
675 | fprintf(stderr, "topology: no memory\n"); | ||
676 | goto exit; | ||
677 | } | ||
678 | |||
679 | for (i = 0; i < sib_core_nr; i++) { | ||
680 | if (str_to_bitmap(sib_core, &t.sib_core[i])) { | ||
681 | fprintf(stderr, "topology: can't parse siblings map\n"); | ||
682 | goto exit; | ||
683 | } | ||
684 | |||
685 | sib_core += strlen(sib_core) + 1; | ||
686 | } | ||
687 | |||
688 | for (i = 0; i < sib_thr_nr; i++) { | ||
689 | if (str_to_bitmap(sib_thr, &t.sib_thr[i])) { | ||
690 | fprintf(stderr, "topology: can't parse siblings map\n"); | ||
691 | goto exit; | ||
692 | } | ||
693 | |||
694 | sib_thr += strlen(sib_thr) + 1; | ||
695 | } | ||
696 | |||
697 | topology_map = malloc(sizeof(int) * MAX_NR_CPUS); | ||
698 | if (!topology_map) { | ||
699 | fprintf(stderr, "topology: no memory\n"); | ||
700 | goto exit; | ||
701 | } | ||
702 | |||
703 | for (i = 0; i < MAX_NR_CPUS; i++) | ||
704 | topology_map[i] = -1; | ||
705 | |||
706 | scan_core_topology(topology_map, &t); | ||
707 | |||
708 | return 0; | ||
709 | |||
710 | exit: | ||
711 | free(t.sib_core); | ||
712 | free(t.sib_thr); | ||
713 | |||
714 | return -1; | ||
715 | } | ||
diff --git a/tools/perf/util/svghelper.h b/tools/perf/util/svghelper.h index fad79ceeac1a..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, const char *type, const char *name); | 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 | ||
@@ -23,7 +23,11 @@ extern void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, cha | |||
23 | extern void svg_interrupt(u64 start, int row, const char *backtrace); | 23 | extern void svg_interrupt(u64 start, int row, const char *backtrace); |
24 | extern void svg_text(int Yslot, u64 start, const char *text); | 24 | extern void svg_text(int Yslot, u64 start, const char *text); |
25 | extern void svg_close(void); | 25 | extern void svg_close(void); |
26 | extern int svg_build_topology_map(char *sib_core, int sib_core_nr, | ||
27 | char *sib_thr, int sib_thr_nr); | ||
26 | 28 | ||
27 | extern int svg_page_width; | 29 | extern int svg_page_width; |
30 | extern u64 svg_highlight; | ||
31 | extern const char *svg_highlight_name; | ||
28 | 32 | ||
29 | #endif /* __PERF_SVGHELPER_H */ | 33 | #endif /* __PERF_SVGHELPER_H */ |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 61eb1cddf01a..923d00040bbf 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -1089,9 +1089,9 @@ static int dso__load_kcore(struct dso *dso, struct map *map, | |||
1089 | * dso__data_read_addr(). | 1089 | * dso__data_read_addr(). |
1090 | */ | 1090 | */ |
1091 | if (dso->kernel == DSO_TYPE_GUEST_KERNEL) | 1091 | if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
1092 | dso->data_type = DSO_BINARY_TYPE__GUEST_KCORE; | 1092 | dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE; |
1093 | else | 1093 | else |
1094 | dso->data_type = DSO_BINARY_TYPE__KCORE; | 1094 | dso->binary_type = DSO_BINARY_TYPE__KCORE; |
1095 | dso__set_long_name(dso, strdup(kcore_filename), true); | 1095 | dso__set_long_name(dso, strdup(kcore_filename), true); |
1096 | 1096 | ||
1097 | close(fd); | 1097 | close(fd); |
@@ -1258,8 +1258,8 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) | |||
1258 | 1258 | ||
1259 | enum dso_binary_type symtab_type = binary_type_symtab[i]; | 1259 | enum dso_binary_type symtab_type = binary_type_symtab[i]; |
1260 | 1260 | ||
1261 | if (dso__binary_type_file(dso, symtab_type, | 1261 | if (dso__read_binary_type_filename(dso, symtab_type, |
1262 | root_dir, name, PATH_MAX)) | 1262 | root_dir, name, PATH_MAX)) |
1263 | continue; | 1263 | continue; |
1264 | 1264 | ||
1265 | /* Name is now the name of the next image to try */ | 1265 | /* Name is now the name of the next image to try */ |
@@ -1368,9 +1368,9 @@ int dso__load_vmlinux(struct dso *dso, struct map *map, | |||
1368 | 1368 | ||
1369 | if (err > 0) { | 1369 | if (err > 0) { |
1370 | if (dso->kernel == DSO_TYPE_GUEST_KERNEL) | 1370 | if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
1371 | dso->data_type = DSO_BINARY_TYPE__GUEST_VMLINUX; | 1371 | dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX; |
1372 | else | 1372 | else |
1373 | dso->data_type = DSO_BINARY_TYPE__VMLINUX; | 1373 | dso->binary_type = DSO_BINARY_TYPE__VMLINUX; |
1374 | dso__set_long_name(dso, vmlinux, vmlinux_allocated); | 1374 | dso__set_long_name(dso, vmlinux, vmlinux_allocated); |
1375 | dso__set_loaded(dso, map->type); | 1375 | dso__set_loaded(dso, map->type); |
1376 | pr_debug("Using %s for symbols\n", symfs_vmlinux); | 1376 | pr_debug("Using %s for symbols\n", symfs_vmlinux); |
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index f3c9e551bd35..c354b95a2348 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #include "../perf.h" | 39 | #include "../perf.h" |
40 | #include "trace-event.h" | 40 | #include "trace-event.h" |
41 | #include <lk/debugfs.h> | 41 | #include <api/fs/debugfs.h> |
42 | #include "evsel.h" | 42 | #include "evsel.h" |
43 | 43 | ||
44 | #define VERSION "0.5" | 44 | #define VERSION "0.5" |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index a1eea3e809a3..9a2c268ad718 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -71,7 +71,7 @@ | |||
71 | #include <linux/magic.h> | 71 | #include <linux/magic.h> |
72 | #include "types.h" | 72 | #include "types.h" |
73 | #include <sys/ttydefaults.h> | 73 | #include <sys/ttydefaults.h> |
74 | #include <lk/debugfs.h> | 74 | #include <api/fs/debugfs.h> |
75 | #include <termios.h> | 75 | #include <termios.h> |
76 | #include <linux/bitops.h> | 76 | #include <linux/bitops.h> |
77 | 77 | ||