aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-script-perl.txt1
-rw-r--r--tools/perf/Documentation/perf-script-python.txt1
-rw-r--r--tools/perf/Documentation/perf-script.txt52
-rw-r--r--tools/perf/Makefile123
-rw-r--r--tools/perf/builtin-record.c2
-rw-r--r--tools/perf/builtin-script.c296
-rw-r--r--tools/perf/builtin-stat.c573
-rw-r--r--tools/perf/builtin-test.c2
-rw-r--r--tools/perf/builtin-top.c8
-rw-r--r--tools/perf/config/feature-tests.mak (renamed from tools/perf/feature-tests.mak)16
-rw-r--r--tools/perf/config/utilities.mak188
-rw-r--r--tools/perf/util/evlist.c153
-rw-r--r--tools/perf/util/evlist.h3
-rw-r--r--tools/perf/util/include/asm/alternative-asm.h8
-rw-r--r--tools/perf/util/include/linux/list.h2
-rw-r--r--tools/perf/util/parse-events.c123
-rw-r--r--tools/perf/util/probe-finder.c73
-rw-r--r--tools/perf/util/probe-finder.h2
-rw-r--r--tools/perf/util/python.c5
-rw-r--r--tools/perf/util/session.c12
-rw-r--r--tools/perf/util/session.h3
-rw-r--r--tools/perf/util/symbol.c629
-rw-r--r--tools/perf/util/symbol.h78
-rw-r--r--tools/perf/util/trace-event-parse.c1
-rwxr-xr-xtools/testing/ktest/ktest.pl156
-rw-r--r--tools/testing/ktest/sample.conf93
26 files changed, 1968 insertions, 635 deletions
diff --git a/tools/perf/Documentation/perf-script-perl.txt b/tools/perf/Documentation/perf-script-perl.txt
index 5bb41e55a3ac..3152cca15501 100644
--- a/tools/perf/Documentation/perf-script-perl.txt
+++ b/tools/perf/Documentation/perf-script-perl.txt
@@ -63,7 +63,6 @@ The format file for the sched_wakep event defines the following fields
63 field:unsigned char common_flags; 63 field:unsigned char common_flags;
64 field:unsigned char common_preempt_count; 64 field:unsigned char common_preempt_count;
65 field:int common_pid; 65 field:int common_pid;
66 field:int common_lock_depth;
67 66
68 field:char comm[TASK_COMM_LEN]; 67 field:char comm[TASK_COMM_LEN];
69 field:pid_t pid; 68 field:pid_t pid;
diff --git a/tools/perf/Documentation/perf-script-python.txt b/tools/perf/Documentation/perf-script-python.txt
index 36b38277422c..471022069119 100644
--- a/tools/perf/Documentation/perf-script-python.txt
+++ b/tools/perf/Documentation/perf-script-python.txt
@@ -463,7 +463,6 @@ The format file for the sched_wakep event defines the following fields
463 field:unsigned char common_flags; 463 field:unsigned char common_flags;
464 field:unsigned char common_preempt_count; 464 field:unsigned char common_preempt_count;
465 field:int common_pid; 465 field:int common_pid;
466 field:int common_lock_depth;
467 466
468 field:char comm[TASK_COMM_LEN]; 467 field:char comm[TASK_COMM_LEN];
469 field:pid_t pid; 468 field:pid_t pid;
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 66f040b30729..86c87e214b11 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -113,13 +113,61 @@ OPTIONS
113 Do various checks like samples ordering and lost events. 113 Do various checks like samples ordering and lost events.
114 114
115-f:: 115-f::
116--fields 116--fields::
117 Comma separated list of fields to print. Options are: 117 Comma separated list of fields to print. Options are:
118 comm, tid, pid, time, cpu, event, trace, sym. Field 118 comm, tid, pid, time, cpu, event, trace, sym. Field
119 list must be prepended with the type, trace, sw or hw, 119 list can be prepended with the type, trace, sw or hw,
120 to indicate to which event type the field list applies. 120 to indicate to which event type the field list applies.
121 e.g., -f sw:comm,tid,time,sym and -f trace:time,cpu,trace 121 e.g., -f sw:comm,tid,time,sym and -f trace:time,cpu,trace
122 122
123 perf script -f <fields>
124
125 is equivalent to:
126
127 perf script -f trace:<fields> -f sw:<fields> -f hw:<fields>
128
129 i.e., the specified fields apply to all event types if the type string
130 is not given.
131
132 The arguments are processed in the order received. A later usage can
133 reset a prior request. e.g.:
134
135 -f trace: -f comm,tid,time,sym
136
137 The first -f suppresses trace events (field list is ""), but then the
138 second invocation sets the fields to comm,tid,time,sym. In this case a
139 warning is given to the user:
140
141 "Overriding previous field request for all events."
142
143 Alternativey, consider the order:
144
145 -f comm,tid,time,sym -f trace:
146
147 The first -f sets the fields for all events and the second -f
148 suppresses trace events. The user is given a warning message about
149 the override, and the result of the above is that only S/W and H/W
150 events are displayed with the given fields.
151
152 For the 'wildcard' option if a user selected field is invalid for an
153 event type, a message is displayed to the user that the option is
154 ignored for that type. For example:
155
156 $ perf script -f comm,tid,trace
157 'trace' not valid for hardware events. Ignoring.
158 'trace' not valid for software events. Ignoring.
159
160 Alternatively, if the type is given an invalid field is specified it
161 is an error. For example:
162
163 perf script -v -f sw:comm,tid,trace
164 'trace' not valid for software events.
165
166 At this point usage is displayed, and perf-script exits.
167
168 Finally, a user may not set fields to none for all event types.
169 i.e., -f "" is not allowed.
170
123-k:: 171-k::
124--vmlinux=<file>:: 172--vmlinux=<file>::
125 vmlinux pathname 173 vmlinux pathname
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 207dee5c5b16..1455413ec7a7 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -5,6 +5,8 @@ endif
5# The default target of this Makefile is... 5# The default target of this Makefile is...
6all: 6all:
7 7
8include config/utilities.mak
9
8ifneq ($(OUTPUT),) 10ifneq ($(OUTPUT),)
9# check that the output directory actually exists 11# check that the output directory actually exists
10OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd) 12OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
@@ -13,6 +15,12 @@ endif
13 15
14# Define V to have a more verbose compile. 16# Define V to have a more verbose compile.
15# 17#
18# Define PYTHON to point to the python binary if the default
19# `python' is not correct; for example: PYTHON=python2
20#
21# Define PYTHON_CONFIG to point to the python-config binary if
22# the default `$(PYTHON)-config' is not correct.
23#
16# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8 24# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
17# 25#
18# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72. 26# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
@@ -35,15 +43,21 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
35 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ 43 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
36 -e s/sh[234].*/sh/ ) 44 -e s/sh[234].*/sh/ )
37 45
46CC = $(CROSS_COMPILE)gcc
47AR = $(CROSS_COMPILE)ar
48
38# Additional ARCH settings for x86 49# Additional ARCH settings for x86
39ifeq ($(ARCH),i386) 50ifeq ($(ARCH),i386)
40 ARCH := x86 51 ARCH := x86
41endif 52endif
42ifeq ($(ARCH),x86_64) 53ifeq ($(ARCH),x86_64)
43 RAW_ARCH := x86_64 54 ARCH := x86
44 ARCH := x86 55 IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1)
45 ARCH_CFLAGS := -DARCH_X86_64 56 ifeq (${IS_X86_64}, 1)
46 ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S 57 RAW_ARCH := x86_64
58 ARCH_CFLAGS := -DARCH_X86_64
59 ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S
60 endif
47endif 61endif
48 62
49# 63#
@@ -119,8 +133,6 @@ lib = lib
119 133
120export prefix bindir sharedir sysconfdir 134export prefix bindir sharedir sysconfdir
121 135
122CC = $(CROSS_COMPILE)gcc
123AR = $(CROSS_COMPILE)ar
124RM = rm -f 136RM = rm -f
125MKDIR = mkdir 137MKDIR = mkdir
126FIND = find 138FIND = find
@@ -130,7 +142,7 @@ INSTALL = install
130# explicitly what architecture to check for. Fix this up for yours.. 142# explicitly what architecture to check for. Fix this up for yours..
131SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ 143SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
132 144
133-include feature-tests.mak 145-include config/feature-tests.mak
134 146
135ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -fstack-protector-all),y) 147ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -fstack-protector-all),y)
136 CFLAGS := $(CFLAGS) -fstack-protector-all 148 CFLAGS := $(CFLAGS) -fstack-protector-all
@@ -165,12 +177,10 @@ grep-libs = $(filter -l%,$(1))
165strip-libs = $(filter-out -l%,$(1)) 177strip-libs = $(filter-out -l%,$(1))
166 178
167$(OUTPUT)python/perf.so: $(PYRF_OBJS) 179$(OUTPUT)python/perf.so: $(PYRF_OBJS)
168 $(QUIET_GEN)( \ 180 $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \
169 export CFLAGS="$(BASIC_CFLAGS)"; \ 181 --quiet build_ext \
170 python util/setup.py --quiet build_ext --build-lib='$(OUTPUT)python' \ 182 --build-lib='$(OUTPUT)python' \
171 --build-temp='$(OUTPUT)python/temp' \ 183 --build-temp='$(OUTPUT)python/temp'
172 )
173
174# 184#
175# No Perl scripts right now: 185# No Perl scripts right now:
176# 186#
@@ -475,24 +485,74 @@ else
475 endif 485 endif
476endif 486endif
477 487
478ifdef NO_LIBPYTHON 488disable-python = $(eval $(disable-python_code))
479 BASIC_CFLAGS += -DNO_LIBPYTHON 489define disable-python_code
490 BASIC_CFLAGS += -DNO_LIBPYTHON
491 $(if $(1),$(warning No $(1) was found))
492 $(warning Python support won't be built)
493endef
494
495override PYTHON := \
496 $(call get-executable-or-default,PYTHON,python)
497
498ifndef PYTHON
499 $(call disable-python,python interpreter)
500 python-clean :=
480else 501else
481 PYTHON_EMBED_LDOPTS = $(shell python-config --ldflags 2>/dev/null) 502
482 PYTHON_EMBED_LDFLAGS = $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) 503 PYTHON_WORD := $(call shell-wordify,$(PYTHON))
483 PYTHON_EMBED_LIBADD = $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) 504
484 PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null` 505 python-clean := $(PYTHON_WORD) util/setup.py clean \
485 FLAGS_PYTHON_EMBED=$(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) 506 --build-lib='$(OUTPUT)python' \
486 ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y) 507 --build-temp='$(OUTPUT)python/temp'
487 msg := $(warning No Python.h found, install python-dev[el] to have python support in 'perf script' and to build the python bindings) 508
488 BASIC_CFLAGS += -DNO_LIBPYTHON 509 ifdef NO_LIBPYTHON
489 else 510 $(call disable-python)
490 ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS) 511 else
491 EXTLIBS += $(PYTHON_EMBED_LIBADD) 512
492 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o 513 override PYTHON_CONFIG := \
493 LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o 514 $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
494 LANG_BINDINGS += $(OUTPUT)python/perf.so 515
495 endif 516 ifndef PYTHON_CONFIG
517 $(call disable-python,python-config tool)
518 else
519
520 PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
521
522 PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
523 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
524 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
525 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
526 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
527
528 ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y)
529 $(call disable-python,Python.h (for Python 2.x))
530 else
531
532 ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED)),y)
533 $(warning Python 3 is not yet supported; please set)
534 $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
535 $(warning If you also have Python 2 installed, then)
536 $(warning try something like:)
537 $(warning $(and ,))
538 $(warning $(and ,) make PYTHON=python2)
539 $(warning $(and ,))
540 $(warning Otherwise, disable Python support entirely:)
541 $(warning $(and ,))
542 $(warning $(and ,) make NO_LIBPYTHON=1)
543 $(warning $(and ,))
544 $(error $(and ,))
545 else
546 ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
547 EXTLIBS += $(PYTHON_EMBED_LIBADD)
548 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
549 LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
550 LANG_BINDINGS += $(OUTPUT)python/perf.so
551 endif
552
553 endif
554 endif
555 endif
496endif 556endif
497 557
498ifdef NO_DEMANGLE 558ifdef NO_DEMANGLE
@@ -833,8 +893,7 @@ clean:
833 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* 893 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
834 $(MAKE) -C Documentation/ clean 894 $(MAKE) -C Documentation/ clean
835 $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS 895 $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
836 @python util/setup.py clean --build-lib='$(OUTPUT)python' \ 896 $(python-clean)
837 --build-temp='$(OUTPUT)python/temp'
838 897
839.PHONY: all install clean strip 898.PHONY: all install clean strip
840.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell 899.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 416538248a4b..0974f957b8fa 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -427,7 +427,7 @@ static void mmap_read_all(void)
427{ 427{
428 int i; 428 int i;
429 429
430 for (i = 0; i < evsel_list->cpus->nr; i++) { 430 for (i = 0; i < evsel_list->nr_mmaps; i++) {
431 if (evsel_list->mmap[i].base) 431 if (evsel_list->mmap[i].base)
432 mmap_read(&evsel_list->mmap[i]); 432 mmap_read(&evsel_list->mmap[i]);
433 } 433 }
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index ac574ea23917..974f6d3f4e53 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -49,57 +49,169 @@ struct output_option {
49}; 49};
50 50
51/* default set to maintain compatibility with current format */ 51/* default set to maintain compatibility with current format */
52static u64 output_fields[PERF_TYPE_MAX] = { 52static struct {
53 [PERF_TYPE_HARDWARE] = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \ 53 bool user_set;
54 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \ 54 bool wildcard_set;
55 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM, 55 u64 fields;
56 56 u64 invalid_fields;
57 [PERF_TYPE_SOFTWARE] = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \ 57} output[PERF_TYPE_MAX] = {
58 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \ 58
59 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM, 59 [PERF_TYPE_HARDWARE] = {
60 60 .user_set = false,
61 [PERF_TYPE_TRACEPOINT] = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \ 61
62 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \ 62 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
63 PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE, 63 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
64 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
65
66 .invalid_fields = PERF_OUTPUT_TRACE,
67 },
68
69 [PERF_TYPE_SOFTWARE] = {
70 .user_set = false,
71
72 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
73 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
74 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
75
76 .invalid_fields = PERF_OUTPUT_TRACE,
77 },
78
79 [PERF_TYPE_TRACEPOINT] = {
80 .user_set = false,
81
82 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
83 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
84 PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE,
85 },
86
87 [PERF_TYPE_RAW] = {
88 .user_set = false,
89
90 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
91 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
92 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
93
94 .invalid_fields = PERF_OUTPUT_TRACE,
95 },
64}; 96};
65 97
66static bool output_set_by_user; 98static bool output_set_by_user(void)
99{
100 int j;
101 for (j = 0; j < PERF_TYPE_MAX; ++j) {
102 if (output[j].user_set)
103 return true;
104 }
105 return false;
106}
107
108static const char *output_field2str(enum perf_output_field field)
109{
110 int i, imax = ARRAY_SIZE(all_output_options);
111 const char *str = "";
112
113 for (i = 0; i < imax; ++i) {
114 if (all_output_options[i].field == field) {
115 str = all_output_options[i].str;
116 break;
117 }
118 }
119 return str;
120}
67 121
68#define PRINT_FIELD(x) (output_fields[attr->type] & PERF_OUTPUT_##x) 122#define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x)
69 123
70static int perf_session__check_attr(struct perf_session *session, 124static int perf_event_attr__check_stype(struct perf_event_attr *attr,
71 struct perf_event_attr *attr) 125 u64 sample_type, const char *sample_msg,
126 enum perf_output_field field)
72{ 127{
128 int type = attr->type;
129 const char *evname;
130
131 if (attr->sample_type & sample_type)
132 return 0;
133
134 if (output[type].user_set) {
135 evname = __event_name(attr->type, attr->config);
136 pr_err("Samples for '%s' event do not have %s attribute set. "
137 "Cannot print '%s' field.\n",
138 evname, sample_msg, output_field2str(field));
139 return -1;
140 }
141
142 /* user did not ask for it explicitly so remove from the default list */
143 output[type].fields &= ~field;
144 evname = __event_name(attr->type, attr->config);
145 pr_debug("Samples for '%s' event do not have %s attribute set. "
146 "Skipping '%s' field.\n",
147 evname, sample_msg, output_field2str(field));
148
149 return 0;
150}
151
152static int perf_evsel__check_attr(struct perf_evsel *evsel,
153 struct perf_session *session)
154{
155 struct perf_event_attr *attr = &evsel->attr;
156
73 if (PRINT_FIELD(TRACE) && 157 if (PRINT_FIELD(TRACE) &&
74 !perf_session__has_traces(session, "record -R")) 158 !perf_session__has_traces(session, "record -R"))
75 return -EINVAL; 159 return -EINVAL;
76 160
77 if (PRINT_FIELD(SYM)) { 161 if (PRINT_FIELD(SYM)) {
78 if (!(session->sample_type & PERF_SAMPLE_IP)) { 162 if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP",
79 pr_err("Samples do not contain IP data.\n"); 163 PERF_OUTPUT_SYM))
80 return -EINVAL; 164 return -EINVAL;
81 } 165
82 if (!no_callchain && 166 if (!no_callchain &&
83 !(session->sample_type & PERF_SAMPLE_CALLCHAIN)) 167 !(attr->sample_type & PERF_SAMPLE_CALLCHAIN))
84 symbol_conf.use_callchain = false; 168 symbol_conf.use_callchain = false;
85 } 169 }
86 170
87 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && 171 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
88 !(session->sample_type & PERF_SAMPLE_TID)) { 172 perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID",
89 pr_err("Samples do not contain TID/PID data.\n"); 173 PERF_OUTPUT_TID|PERF_OUTPUT_PID))
90 return -EINVAL; 174 return -EINVAL;
91 }
92 175
93 if (PRINT_FIELD(TIME) && 176 if (PRINT_FIELD(TIME) &&
94 !(session->sample_type & PERF_SAMPLE_TIME)) { 177 perf_event_attr__check_stype(attr, PERF_SAMPLE_TIME, "TIME",
95 pr_err("Samples do not contain timestamps.\n"); 178 PERF_OUTPUT_TIME))
96 return -EINVAL; 179 return -EINVAL;
97 }
98 180
99 if (PRINT_FIELD(CPU) && 181 if (PRINT_FIELD(CPU) &&
100 !(session->sample_type & PERF_SAMPLE_CPU)) { 182 perf_event_attr__check_stype(attr, PERF_SAMPLE_CPU, "CPU",
101 pr_err("Samples do not contain cpu.\n"); 183 PERF_OUTPUT_CPU))
102 return -EINVAL; 184 return -EINVAL;
185
186 return 0;
187}
188
189/*
190 * verify all user requested events exist and the samples
191 * have the expected data
192 */
193static int perf_session__check_output_opt(struct perf_session *session)
194{
195 int j;
196 struct perf_evsel *evsel;
197
198 for (j = 0; j < PERF_TYPE_MAX; ++j) {
199 evsel = perf_session__find_first_evtype(session, j);
200
201 /*
202 * even if fields is set to 0 (ie., show nothing) event must
203 * exist if user explicitly includes it on the command line
204 */
205 if (!evsel && output[j].user_set && !output[j].wildcard_set) {
206 pr_err("%s events do not exist. "
207 "Remove corresponding -f option to proceed.\n",
208 event_type(j));
209 return -1;
210 }
211
212 if (evsel && output[j].fields &&
213 perf_evsel__check_attr(evsel, session))
214 return -1;
103 } 215 }
104 216
105 return 0; 217 return 0;
@@ -168,10 +280,7 @@ static void process_event(union perf_event *event __unused,
168{ 280{
169 struct perf_event_attr *attr = &evsel->attr; 281 struct perf_event_attr *attr = &evsel->attr;
170 282
171 if (output_fields[attr->type] == 0) 283 if (output[attr->type].fields == 0)
172 return;
173
174 if (perf_session__check_attr(session, attr) < 0)
175 return; 284 return;
176 285
177 print_sample_start(sample, thread, attr); 286 print_sample_start(sample, thread, attr);
@@ -451,6 +560,7 @@ static int parse_output_fields(const struct option *opt __used,
451{ 560{
452 char *tok; 561 char *tok;
453 int i, imax = sizeof(all_output_options) / sizeof(struct output_option); 562 int i, imax = sizeof(all_output_options) / sizeof(struct output_option);
563 int j;
454 int rc = 0; 564 int rc = 0;
455 char *str = strdup(arg); 565 char *str = strdup(arg);
456 int type = -1; 566 int type = -1;
@@ -458,52 +568,99 @@ static int parse_output_fields(const struct option *opt __used,
458 if (!str) 568 if (!str)
459 return -ENOMEM; 569 return -ENOMEM;
460 570
461 tok = strtok(str, ":"); 571 /* first word can state for which event type the user is specifying
462 if (!tok) { 572 * the fields. If no type exists, the specified fields apply to all
463 fprintf(stderr, 573 * event types found in the file minus the invalid fields for a type.
464 "Invalid field string - not prepended with type.");
465 return -EINVAL;
466 }
467
468 /* first word should state which event type user
469 * is specifying the fields
470 */ 574 */
471 if (!strcmp(tok, "hw")) 575 tok = strchr(str, ':');
472 type = PERF_TYPE_HARDWARE; 576 if (tok) {
473 else if (!strcmp(tok, "sw")) 577 *tok = '\0';
474 type = PERF_TYPE_SOFTWARE; 578 tok++;
475 else if (!strcmp(tok, "trace")) 579 if (!strcmp(str, "hw"))
476 type = PERF_TYPE_TRACEPOINT; 580 type = PERF_TYPE_HARDWARE;
477 else { 581 else if (!strcmp(str, "sw"))
478 fprintf(stderr, "Invalid event type in field string."); 582 type = PERF_TYPE_SOFTWARE;
479 return -EINVAL; 583 else if (!strcmp(str, "trace"))
584 type = PERF_TYPE_TRACEPOINT;
585 else if (!strcmp(str, "raw"))
586 type = PERF_TYPE_RAW;
587 else {
588 fprintf(stderr, "Invalid event type in field string.\n");
589 return -EINVAL;
590 }
591
592 if (output[type].user_set)
593 pr_warning("Overriding previous field request for %s events.\n",
594 event_type(type));
595
596 output[type].fields = 0;
597 output[type].user_set = true;
598 output[type].wildcard_set = false;
599
600 } else {
601 tok = str;
602 if (strlen(str) == 0) {
603 fprintf(stderr,
604 "Cannot set fields to 'none' for all event types.\n");
605 rc = -EINVAL;
606 goto out;
607 }
608
609 if (output_set_by_user())
610 pr_warning("Overriding previous field request for all events.\n");
611
612 for (j = 0; j < PERF_TYPE_MAX; ++j) {
613 output[j].fields = 0;
614 output[j].user_set = true;
615 output[j].wildcard_set = true;
616 }
480 } 617 }
481 618
482 output_fields[type] = 0; 619 tok = strtok(tok, ",");
483 while (1) { 620 while (tok) {
484 tok = strtok(NULL, ",");
485 if (!tok)
486 break;
487 for (i = 0; i < imax; ++i) { 621 for (i = 0; i < imax; ++i) {
488 if (strcmp(tok, all_output_options[i].str) == 0) { 622 if (strcmp(tok, all_output_options[i].str) == 0)
489 output_fields[type] |= all_output_options[i].field;
490 break; 623 break;
491 }
492 } 624 }
493 if (i == imax) { 625 if (i == imax) {
494 fprintf(stderr, "Invalid field requested."); 626 fprintf(stderr, "Invalid field requested.\n");
495 rc = -EINVAL; 627 rc = -EINVAL;
496 break; 628 goto out;
497 } 629 }
498 }
499 630
500 if (output_fields[type] == 0) { 631 if (type == -1) {
501 pr_debug("No fields requested for %s type. " 632 /* add user option to all events types for
502 "Events will not be displayed\n", event_type(type)); 633 * which it is valid
634 */
635 for (j = 0; j < PERF_TYPE_MAX; ++j) {
636 if (output[j].invalid_fields & all_output_options[i].field) {
637 pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
638 all_output_options[i].str, event_type(j));
639 } else
640 output[j].fields |= all_output_options[i].field;
641 }
642 } else {
643 if (output[type].invalid_fields & all_output_options[i].field) {
644 fprintf(stderr, "\'%s\' not valid for %s events.\n",
645 all_output_options[i].str, event_type(type));
646
647 rc = -EINVAL;
648 goto out;
649 }
650 output[type].fields |= all_output_options[i].field;
651 }
652
653 tok = strtok(NULL, ",");
503 } 654 }
504 655
505 output_set_by_user = true; 656 if (type >= 0) {
657 if (output[type].fields == 0) {
658 pr_debug("No fields requested for %s type. "
659 "Events will not be displayed.\n", event_type(type));
660 }
661 }
506 662
663out:
507 free(str); 664 free(str);
508 return rc; 665 return rc;
509} 666}
@@ -829,7 +986,7 @@ static const struct option options[] = {
829 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 986 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
830 "Look for files with symbols relative to this directory"), 987 "Look for files with symbols relative to this directory"),
831 OPT_CALLBACK('f', "fields", NULL, "str", 988 OPT_CALLBACK('f', "fields", NULL, "str",
832 "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace. Fields: comm,tid,pid,time,cpu,event,trace,sym", 989 "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,sym",
833 parse_output_fields), 990 parse_output_fields),
834 991
835 OPT_END() 992 OPT_END()
@@ -1020,7 +1177,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1020 struct stat perf_stat; 1177 struct stat perf_stat;
1021 int input; 1178 int input;
1022 1179
1023 if (output_set_by_user) { 1180 if (output_set_by_user()) {
1024 fprintf(stderr, 1181 fprintf(stderr,
1025 "custom fields not supported for generated scripts"); 1182 "custom fields not supported for generated scripts");
1026 return -1; 1183 return -1;
@@ -1060,6 +1217,11 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1060 pr_debug("perf script started with script %s\n\n", script_name); 1217 pr_debug("perf script started with script %s\n\n", script_name);
1061 } 1218 }
1062 1219
1220
1221 err = perf_session__check_output_opt(session);
1222 if (err < 0)
1223 goto out;
1224
1063 err = __cmd_script(session); 1225 err = __cmd_script(session);
1064 1226
1065 perf_session__delete(session); 1227 perf_session__delete(session);
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 03f0e45f1479..a9f06715e44d 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -6,24 +6,28 @@
6 * 6 *
7 * Sample output: 7 * Sample output:
8 8
9 $ perf stat ~/hackbench 10 9 $ perf stat ./hackbench 10
10 Time: 0.104
11 10
12 Performance counter stats for '/home/mingo/hackbench': 11 Time: 0.118
13 12
14 1255.538611 task clock ticks # 10.143 CPU utilization factor 13 Performance counter stats for './hackbench 10':
15 54011 context switches # 0.043 M/sec
16 385 CPU migrations # 0.000 M/sec
17 17755 pagefaults # 0.014 M/sec
18 3808323185 CPU cycles # 3033.219 M/sec
19 1575111190 instructions # 1254.530 M/sec
20 17367895 cache references # 13.833 M/sec
21 7674421 cache misses # 6.112 M/sec
22 14
23 Wall-clock time elapsed: 123.786620 msecs 15 1708.761321 task-clock # 11.037 CPUs utilized
16 41,190 context-switches # 0.024 M/sec
17 6,735 CPU-migrations # 0.004 M/sec
18 17,318 page-faults # 0.010 M/sec
19 5,205,202,243 cycles # 3.046 GHz
20 3,856,436,920 stalled-cycles-frontend # 74.09% frontend cycles idle
21 1,600,790,871 stalled-cycles-backend # 30.75% backend cycles idle
22 2,603,501,247 instructions # 0.50 insns per cycle
23 # 1.48 stalled cycles per insn
24 484,357,498 branches # 283.455 M/sec
25 6,388,934 branch-misses # 1.32% of all branches
26
27 0.154822978 seconds time elapsed
24 28
25 * 29 *
26 * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com> 30 * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
27 * 31 *
28 * Improvements and fixes by: 32 * Improvements and fixes by:
29 * 33 *
@@ -46,6 +50,7 @@
46#include "util/evlist.h" 50#include "util/evlist.h"
47#include "util/evsel.h" 51#include "util/evsel.h"
48#include "util/debug.h" 52#include "util/debug.h"
53#include "util/color.h"
49#include "util/header.h" 54#include "util/header.h"
50#include "util/cpumap.h" 55#include "util/cpumap.h"
51#include "util/thread.h" 56#include "util/thread.h"
@@ -65,14 +70,107 @@ static struct perf_event_attr default_attrs[] = {
65 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS }, 70 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
66 71
67 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES }, 72 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
73 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
74 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
68 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS }, 75 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
69 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 76 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
70 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES }, 77 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES },
71 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_REFERENCES },
72 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_MISSES },
73 78
74}; 79};
75 80
81/*
82 * Detailed stats (-d), covering the L1 and last level data caches:
83 */
84static struct perf_event_attr detailed_attrs[] = {
85
86 { .type = PERF_TYPE_HW_CACHE,
87 .config =
88 PERF_COUNT_HW_CACHE_L1D << 0 |
89 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
90 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
91
92 { .type = PERF_TYPE_HW_CACHE,
93 .config =
94 PERF_COUNT_HW_CACHE_L1D << 0 |
95 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
96 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
97
98 { .type = PERF_TYPE_HW_CACHE,
99 .config =
100 PERF_COUNT_HW_CACHE_LL << 0 |
101 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
102 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
103
104 { .type = PERF_TYPE_HW_CACHE,
105 .config =
106 PERF_COUNT_HW_CACHE_LL << 0 |
107 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
108 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
109};
110
111/*
112 * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
113 */
114static struct perf_event_attr very_detailed_attrs[] = {
115
116 { .type = PERF_TYPE_HW_CACHE,
117 .config =
118 PERF_COUNT_HW_CACHE_L1I << 0 |
119 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
120 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
121
122 { .type = PERF_TYPE_HW_CACHE,
123 .config =
124 PERF_COUNT_HW_CACHE_L1I << 0 |
125 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
126 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
127
128 { .type = PERF_TYPE_HW_CACHE,
129 .config =
130 PERF_COUNT_HW_CACHE_DTLB << 0 |
131 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
132 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
133
134 { .type = PERF_TYPE_HW_CACHE,
135 .config =
136 PERF_COUNT_HW_CACHE_DTLB << 0 |
137 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
138 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
139
140 { .type = PERF_TYPE_HW_CACHE,
141 .config =
142 PERF_COUNT_HW_CACHE_ITLB << 0 |
143 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
144 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
145
146 { .type = PERF_TYPE_HW_CACHE,
147 .config =
148 PERF_COUNT_HW_CACHE_ITLB << 0 |
149 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
150 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
151
152};
153
154/*
155 * Very, very detailed stats (-d -d -d), adding prefetch events:
156 */
157static struct perf_event_attr very_very_detailed_attrs[] = {
158
159 { .type = PERF_TYPE_HW_CACHE,
160 .config =
161 PERF_COUNT_HW_CACHE_L1D << 0 |
162 (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
163 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
164
165 { .type = PERF_TYPE_HW_CACHE,
166 .config =
167 PERF_COUNT_HW_CACHE_L1D << 0 |
168 (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
169 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
170};
171
172
173
76struct perf_evlist *evsel_list; 174struct perf_evlist *evsel_list;
77 175
78static bool system_wide = false; 176static bool system_wide = false;
@@ -86,6 +184,8 @@ static pid_t target_pid = -1;
86static pid_t target_tid = -1; 184static pid_t target_tid = -1;
87static pid_t child_pid = -1; 185static pid_t child_pid = -1;
88static bool null_run = false; 186static bool null_run = false;
187static int detailed_run = 0;
188static bool sync_run = false;
89static bool big_num = true; 189static bool big_num = true;
90static int big_num_opt = -1; 190static int big_num_opt = -1;
91static const char *cpu_list; 191static const char *cpu_list;
@@ -156,7 +256,15 @@ static double stddev_stats(struct stats *stats)
156 256
157struct stats runtime_nsecs_stats[MAX_NR_CPUS]; 257struct stats runtime_nsecs_stats[MAX_NR_CPUS];
158struct stats runtime_cycles_stats[MAX_NR_CPUS]; 258struct stats runtime_cycles_stats[MAX_NR_CPUS];
259struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS];
260struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS];
159struct stats runtime_branches_stats[MAX_NR_CPUS]; 261struct stats runtime_branches_stats[MAX_NR_CPUS];
262struct stats runtime_cacherefs_stats[MAX_NR_CPUS];
263struct stats runtime_l1_dcache_stats[MAX_NR_CPUS];
264struct stats runtime_l1_icache_stats[MAX_NR_CPUS];
265struct stats runtime_ll_cache_stats[MAX_NR_CPUS];
266struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
267struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
160struct stats walltime_nsecs_stats; 268struct stats walltime_nsecs_stats;
161 269
162static int create_perf_stat_counter(struct perf_evsel *evsel) 270static int create_perf_stat_counter(struct perf_evsel *evsel)
@@ -193,6 +301,37 @@ static inline int nsec_counter(struct perf_evsel *evsel)
193} 301}
194 302
195/* 303/*
304 * Update various tracking values we maintain to print
305 * more semantic information such as miss/hit ratios,
306 * instruction rates, etc:
307 */
308static void update_shadow_stats(struct perf_evsel *counter, u64 *count)
309{
310 if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
311 update_stats(&runtime_nsecs_stats[0], count[0]);
312 else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
313 update_stats(&runtime_cycles_stats[0], count[0]);
314 else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
315 update_stats(&runtime_stalled_cycles_front_stats[0], count[0]);
316 else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
317 update_stats(&runtime_stalled_cycles_back_stats[0], count[0]);
318 else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
319 update_stats(&runtime_branches_stats[0], count[0]);
320 else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES))
321 update_stats(&runtime_cacherefs_stats[0], count[0]);
322 else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D))
323 update_stats(&runtime_l1_dcache_stats[0], count[0]);
324 else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I))
325 update_stats(&runtime_l1_icache_stats[0], count[0]);
326 else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL))
327 update_stats(&runtime_ll_cache_stats[0], count[0]);
328 else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB))
329 update_stats(&runtime_dtlb_cache_stats[0], count[0]);
330 else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
331 update_stats(&runtime_itlb_cache_stats[0], count[0]);
332}
333
334/*
196 * Read out the results of a single counter: 335 * Read out the results of a single counter:
197 * aggregate counts across CPUs in system-wide mode 336 * aggregate counts across CPUs in system-wide mode
198 */ 337 */
@@ -217,12 +356,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
217 /* 356 /*
218 * Save the full runtime - to allow normalization during printout: 357 * Save the full runtime - to allow normalization during printout:
219 */ 358 */
220 if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK)) 359 update_shadow_stats(counter, count);
221 update_stats(&runtime_nsecs_stats[0], count[0]);
222 if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
223 update_stats(&runtime_cycles_stats[0], count[0]);
224 if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
225 update_stats(&runtime_branches_stats[0], count[0]);
226 360
227 return 0; 361 return 0;
228} 362}
@@ -242,12 +376,7 @@ static int read_counter(struct perf_evsel *counter)
242 376
243 count = counter->counts->cpu[cpu].values; 377 count = counter->counts->cpu[cpu].values;
244 378
245 if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK)) 379 update_shadow_stats(counter, count);
246 update_stats(&runtime_nsecs_stats[cpu], count[0]);
247 if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
248 update_stats(&runtime_cycles_stats[cpu], count[0]);
249 if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
250 update_stats(&runtime_branches_stats[cpu], count[0]);
251 } 380 }
252 381
253 return 0; 382 return 0;
@@ -315,13 +444,18 @@ static int run_perf_stat(int argc __used, const char **argv)
315 444
316 list_for_each_entry(counter, &evsel_list->entries, node) { 445 list_for_each_entry(counter, &evsel_list->entries, node) {
317 if (create_perf_stat_counter(counter) < 0) { 446 if (create_perf_stat_counter(counter) < 0) {
318 if (errno == -EPERM || errno == -EACCES) { 447 if (errno == EINVAL || errno == ENOSYS || errno == ENOENT) {
448 if (verbose)
449 ui__warning("%s event is not supported by the kernel.\n",
450 event_name(counter));
451 continue;
452 }
453
454 if (errno == EPERM || errno == EACCES) {
319 error("You may not have permission to collect %sstats.\n" 455 error("You may not have permission to collect %sstats.\n"
320 "\t Consider tweaking" 456 "\t Consider tweaking"
321 " /proc/sys/kernel/perf_event_paranoid or running as root.", 457 " /proc/sys/kernel/perf_event_paranoid or running as root.",
322 system_wide ? "system-wide " : ""); 458 system_wide ? "system-wide " : "");
323 } else if (errno == ENOENT) {
324 error("%s event is not supported. ", event_name(counter));
325 } else { 459 } else {
326 error("open_counter returned with %d (%s). " 460 error("open_counter returned with %d (%s). "
327 "/bin/dmesg may provide additional information.\n", 461 "/bin/dmesg may provide additional information.\n",
@@ -372,6 +506,16 @@ static int run_perf_stat(int argc __used, const char **argv)
372 return WEXITSTATUS(status); 506 return WEXITSTATUS(status);
373} 507}
374 508
509static void print_noise_pct(double total, double avg)
510{
511 double pct = 0.0;
512
513 if (avg)
514 pct = 100.0*total/avg;
515
516 fprintf(stderr, " ( +-%6.2f%% )", pct);
517}
518
375static void print_noise(struct perf_evsel *evsel, double avg) 519static void print_noise(struct perf_evsel *evsel, double avg)
376{ 520{
377 struct perf_stat *ps; 521 struct perf_stat *ps;
@@ -380,15 +524,14 @@ static void print_noise(struct perf_evsel *evsel, double avg)
380 return; 524 return;
381 525
382 ps = evsel->priv; 526 ps = evsel->priv;
383 fprintf(stderr, " ( +- %7.3f%% )", 527 print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
384 100 * stddev_stats(&ps->res_stats[0]) / avg);
385} 528}
386 529
387static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg) 530static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
388{ 531{
389 double msecs = avg / 1e6; 532 double msecs = avg / 1e6;
390 char cpustr[16] = { '\0', }; 533 char cpustr[16] = { '\0', };
391 const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-24s"; 534 const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-25s";
392 535
393 if (no_aggr) 536 if (no_aggr)
394 sprintf(cpustr, "CPU%*d%s", 537 sprintf(cpustr, "CPU%*d%s",
@@ -404,8 +547,191 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
404 return; 547 return;
405 548
406 if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 549 if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
407 fprintf(stderr, " # %10.3f CPUs ", 550 fprintf(stderr, " # %8.3f CPUs utilized ", avg / avg_stats(&walltime_nsecs_stats));
408 avg / avg_stats(&walltime_nsecs_stats)); 551}
552
553static void print_stalled_cycles_frontend(int cpu, struct perf_evsel *evsel __used, double avg)
554{
555 double total, ratio = 0.0;
556 const char *color;
557
558 total = avg_stats(&runtime_cycles_stats[cpu]);
559
560 if (total)
561 ratio = avg / total * 100.0;
562
563 color = PERF_COLOR_NORMAL;
564 if (ratio > 50.0)
565 color = PERF_COLOR_RED;
566 else if (ratio > 30.0)
567 color = PERF_COLOR_MAGENTA;
568 else if (ratio > 10.0)
569 color = PERF_COLOR_YELLOW;
570
571 fprintf(stderr, " # ");
572 color_fprintf(stderr, color, "%6.2f%%", ratio);
573 fprintf(stderr, " frontend cycles idle ");
574}
575
576static void print_stalled_cycles_backend(int cpu, struct perf_evsel *evsel __used, double avg)
577{
578 double total, ratio = 0.0;
579 const char *color;
580
581 total = avg_stats(&runtime_cycles_stats[cpu]);
582
583 if (total)
584 ratio = avg / total * 100.0;
585
586 color = PERF_COLOR_NORMAL;
587 if (ratio > 75.0)
588 color = PERF_COLOR_RED;
589 else if (ratio > 50.0)
590 color = PERF_COLOR_MAGENTA;
591 else if (ratio > 20.0)
592 color = PERF_COLOR_YELLOW;
593
594 fprintf(stderr, " # ");
595 color_fprintf(stderr, color, "%6.2f%%", ratio);
596 fprintf(stderr, " backend cycles idle ");
597}
598
599static void print_branch_misses(int cpu, struct perf_evsel *evsel __used, double avg)
600{
601 double total, ratio = 0.0;
602 const char *color;
603
604 total = avg_stats(&runtime_branches_stats[cpu]);
605
606 if (total)
607 ratio = avg / total * 100.0;
608
609 color = PERF_COLOR_NORMAL;
610 if (ratio > 20.0)
611 color = PERF_COLOR_RED;
612 else if (ratio > 10.0)
613 color = PERF_COLOR_MAGENTA;
614 else if (ratio > 5.0)
615 color = PERF_COLOR_YELLOW;
616
617 fprintf(stderr, " # ");
618 color_fprintf(stderr, color, "%6.2f%%", ratio);
619 fprintf(stderr, " of all branches ");
620}
621
622static void print_l1_dcache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
623{
624 double total, ratio = 0.0;
625 const char *color;
626
627 total = avg_stats(&runtime_l1_dcache_stats[cpu]);
628
629 if (total)
630 ratio = avg / total * 100.0;
631
632 color = PERF_COLOR_NORMAL;
633 if (ratio > 20.0)
634 color = PERF_COLOR_RED;
635 else if (ratio > 10.0)
636 color = PERF_COLOR_MAGENTA;
637 else if (ratio > 5.0)
638 color = PERF_COLOR_YELLOW;
639
640 fprintf(stderr, " # ");
641 color_fprintf(stderr, color, "%6.2f%%", ratio);
642 fprintf(stderr, " of all L1-dcache hits ");
643}
644
645static void print_l1_icache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
646{
647 double total, ratio = 0.0;
648 const char *color;
649
650 total = avg_stats(&runtime_l1_icache_stats[cpu]);
651
652 if (total)
653 ratio = avg / total * 100.0;
654
655 color = PERF_COLOR_NORMAL;
656 if (ratio > 20.0)
657 color = PERF_COLOR_RED;
658 else if (ratio > 10.0)
659 color = PERF_COLOR_MAGENTA;
660 else if (ratio > 5.0)
661 color = PERF_COLOR_YELLOW;
662
663 fprintf(stderr, " # ");
664 color_fprintf(stderr, color, "%6.2f%%", ratio);
665 fprintf(stderr, " of all L1-icache hits ");
666}
667
668static void print_dtlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
669{
670 double total, ratio = 0.0;
671 const char *color;
672
673 total = avg_stats(&runtime_dtlb_cache_stats[cpu]);
674
675 if (total)
676 ratio = avg / total * 100.0;
677
678 color = PERF_COLOR_NORMAL;
679 if (ratio > 20.0)
680 color = PERF_COLOR_RED;
681 else if (ratio > 10.0)
682 color = PERF_COLOR_MAGENTA;
683 else if (ratio > 5.0)
684 color = PERF_COLOR_YELLOW;
685
686 fprintf(stderr, " # ");
687 color_fprintf(stderr, color, "%6.2f%%", ratio);
688 fprintf(stderr, " of all dTLB cache hits ");
689}
690
691static void print_itlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
692{
693 double total, ratio = 0.0;
694 const char *color;
695
696 total = avg_stats(&runtime_itlb_cache_stats[cpu]);
697
698 if (total)
699 ratio = avg / total * 100.0;
700
701 color = PERF_COLOR_NORMAL;
702 if (ratio > 20.0)
703 color = PERF_COLOR_RED;
704 else if (ratio > 10.0)
705 color = PERF_COLOR_MAGENTA;
706 else if (ratio > 5.0)
707 color = PERF_COLOR_YELLOW;
708
709 fprintf(stderr, " # ");
710 color_fprintf(stderr, color, "%6.2f%%", ratio);
711 fprintf(stderr, " of all iTLB cache hits ");
712}
713
714static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
715{
716 double total, ratio = 0.0;
717 const char *color;
718
719 total = avg_stats(&runtime_ll_cache_stats[cpu]);
720
721 if (total)
722 ratio = avg / total * 100.0;
723
724 color = PERF_COLOR_NORMAL;
725 if (ratio > 20.0)
726 color = PERF_COLOR_RED;
727 else if (ratio > 10.0)
728 color = PERF_COLOR_MAGENTA;
729 else if (ratio > 5.0)
730 color = PERF_COLOR_YELLOW;
731
732 fprintf(stderr, " # ");
733 color_fprintf(stderr, color, "%6.2f%%", ratio);
734 fprintf(stderr, " of all LL-cache hits ");
409} 735}
410 736
411static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) 737static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
@@ -417,9 +743,9 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
417 if (csv_output) 743 if (csv_output)
418 fmt = "%s%.0f%s%s"; 744 fmt = "%s%.0f%s%s";
419 else if (big_num) 745 else if (big_num)
420 fmt = "%s%'18.0f%s%-24s"; 746 fmt = "%s%'18.0f%s%-25s";
421 else 747 else
422 fmt = "%s%18.0f%s%-24s"; 748 fmt = "%s%18.0f%s%-25s";
423 749
424 if (no_aggr) 750 if (no_aggr)
425 sprintf(cpustr, "CPU%*d%s", 751 sprintf(cpustr, "CPU%*d%s",
@@ -442,23 +768,83 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
442 if (total) 768 if (total)
443 ratio = avg / total; 769 ratio = avg / total;
444 770
445 fprintf(stderr, " # %10.3f IPC ", ratio); 771 fprintf(stderr, " # %5.2f insns per cycle ", ratio);
772
773 total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]);
774 total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu]));
775
776 if (total && avg) {
777 ratio = total / avg;
778 fprintf(stderr, "\n # %5.2f stalled cycles per insn", ratio);
779 }
780
446 } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) && 781 } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
447 runtime_branches_stats[cpu].n != 0) { 782 runtime_branches_stats[cpu].n != 0) {
448 total = avg_stats(&runtime_branches_stats[cpu]); 783 print_branch_misses(cpu, evsel, avg);
784 } else if (
785 evsel->attr.type == PERF_TYPE_HW_CACHE &&
786 evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1D |
787 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
788 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
789 runtime_l1_dcache_stats[cpu].n != 0) {
790 print_l1_dcache_misses(cpu, evsel, avg);
791 } else if (
792 evsel->attr.type == PERF_TYPE_HW_CACHE &&
793 evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1I |
794 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
795 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
796 runtime_l1_icache_stats[cpu].n != 0) {
797 print_l1_icache_misses(cpu, evsel, avg);
798 } else if (
799 evsel->attr.type == PERF_TYPE_HW_CACHE &&
800 evsel->attr.config == ( PERF_COUNT_HW_CACHE_DTLB |
801 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
802 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
803 runtime_dtlb_cache_stats[cpu].n != 0) {
804 print_dtlb_cache_misses(cpu, evsel, avg);
805 } else if (
806 evsel->attr.type == PERF_TYPE_HW_CACHE &&
807 evsel->attr.config == ( PERF_COUNT_HW_CACHE_ITLB |
808 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
809 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
810 runtime_itlb_cache_stats[cpu].n != 0) {
811 print_itlb_cache_misses(cpu, evsel, avg);
812 } else if (
813 evsel->attr.type == PERF_TYPE_HW_CACHE &&
814 evsel->attr.config == ( PERF_COUNT_HW_CACHE_LL |
815 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
816 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
817 runtime_ll_cache_stats[cpu].n != 0) {
818 print_ll_cache_misses(cpu, evsel, avg);
819 } else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
820 runtime_cacherefs_stats[cpu].n != 0) {
821 total = avg_stats(&runtime_cacherefs_stats[cpu]);
449 822
450 if (total) 823 if (total)
451 ratio = avg * 100 / total; 824 ratio = avg * 100 / total;
452 825
453 fprintf(stderr, " # %10.3f %% ", ratio); 826 fprintf(stderr, " # %8.3f %% of all cache refs ", ratio);
827
828 } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
829 print_stalled_cycles_frontend(cpu, evsel, avg);
830 } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
831 print_stalled_cycles_backend(cpu, evsel, avg);
832 } else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
833 total = avg_stats(&runtime_nsecs_stats[cpu]);
454 834
835 if (total)
836 ratio = 1.0 * avg / total;
837
838 fprintf(stderr, " # %8.3f GHz ", ratio);
455 } else if (runtime_nsecs_stats[cpu].n != 0) { 839 } else if (runtime_nsecs_stats[cpu].n != 0) {
456 total = avg_stats(&runtime_nsecs_stats[cpu]); 840 total = avg_stats(&runtime_nsecs_stats[cpu]);
457 841
458 if (total) 842 if (total)
459 ratio = 1000.0 * avg / total; 843 ratio = 1000.0 * avg / total;
460 844
461 fprintf(stderr, " # %10.3f M/sec", ratio); 845 fprintf(stderr, " # %8.3f M/sec ", ratio);
846 } else {
847 fprintf(stderr, " ");
462 } 848 }
463} 849}
464 850
@@ -505,8 +891,7 @@ static void print_counter_aggr(struct perf_evsel *counter)
505 avg_enabled = avg_stats(&ps->res_stats[1]); 891 avg_enabled = avg_stats(&ps->res_stats[1]);
506 avg_running = avg_stats(&ps->res_stats[2]); 892 avg_running = avg_stats(&ps->res_stats[2]);
507 893
508 fprintf(stderr, " (scaled from %.2f%%)", 894 fprintf(stderr, " [%5.2f%%]", 100 * avg_running / avg_enabled);
509 100 * avg_running / avg_enabled);
510 } 895 }
511 fprintf(stderr, "\n"); 896 fprintf(stderr, "\n");
512} 897}
@@ -548,10 +933,8 @@ static void print_counter(struct perf_evsel *counter)
548 if (!csv_output) { 933 if (!csv_output) {
549 print_noise(counter, 1.0); 934 print_noise(counter, 1.0);
550 935
551 if (run != ena) { 936 if (run != ena)
552 fprintf(stderr, " (scaled from %.2f%%)", 937 fprintf(stderr, " (%.2f%%)", 100.0 * run / ena);
553 100.0 * run / ena);
554 }
555 } 938 }
556 fputc('\n', stderr); 939 fputc('\n', stderr);
557 } 940 }
@@ -591,13 +974,14 @@ static void print_stat(int argc, const char **argv)
591 } 974 }
592 975
593 if (!csv_output) { 976 if (!csv_output) {
594 fprintf(stderr, "\n"); 977 if (!null_run)
595 fprintf(stderr, " %18.9f seconds time elapsed", 978 fprintf(stderr, "\n");
979 fprintf(stderr, " %17.9f seconds time elapsed",
596 avg_stats(&walltime_nsecs_stats)/1e9); 980 avg_stats(&walltime_nsecs_stats)/1e9);
597 if (run_count > 1) { 981 if (run_count > 1) {
598 fprintf(stderr, " ( +- %7.3f%% )", 982 fprintf(stderr, " ");
599 100*stddev_stats(&walltime_nsecs_stats) / 983 print_noise_pct(stddev_stats(&walltime_nsecs_stats),
600 avg_stats(&walltime_nsecs_stats)); 984 avg_stats(&walltime_nsecs_stats));
601 } 985 }
602 fprintf(stderr, "\n\n"); 986 fprintf(stderr, "\n\n");
603 } 987 }
@@ -659,6 +1043,10 @@ static const struct option options[] = {
659 "repeat command and print average + stddev (max: 100)"), 1043 "repeat command and print average + stddev (max: 100)"),
660 OPT_BOOLEAN('n', "null", &null_run, 1044 OPT_BOOLEAN('n', "null", &null_run,
661 "null run - dont start any counters"), 1045 "null run - dont start any counters"),
1046 OPT_INCR('d', "detailed", &detailed_run,
1047 "detailed run - start a lot of events"),
1048 OPT_BOOLEAN('S', "sync", &sync_run,
1049 "call sync() before starting a run"),
662 OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, 1050 OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
663 "print large numbers with thousands\' separators", 1051 "print large numbers with thousands\' separators",
664 stat__set_big_num), 1052 stat__set_big_num),
@@ -674,6 +1062,70 @@ static const struct option options[] = {
674 OPT_END() 1062 OPT_END()
675}; 1063};
676 1064
1065/*
1066 * Add default attributes, if there were no attributes specified or
1067 * if -d/--detailed, -d -d or -d -d -d is used:
1068 */
1069static int add_default_attributes(void)
1070{
1071 struct perf_evsel *pos;
1072 size_t attr_nr = 0;
1073 size_t c;
1074
1075 /* Set attrs if no event is selected and !null_run: */
1076 if (null_run)
1077 return 0;
1078
1079 if (!evsel_list->nr_entries) {
1080 for (c = 0; c < ARRAY_SIZE(default_attrs); c++) {
1081 pos = perf_evsel__new(default_attrs + c, c + attr_nr);
1082 if (pos == NULL)
1083 return -1;
1084 perf_evlist__add(evsel_list, pos);
1085 }
1086 attr_nr += c;
1087 }
1088
1089 /* Detailed events get appended to the event list: */
1090
1091 if (detailed_run < 1)
1092 return 0;
1093
1094 /* Append detailed run extra attributes: */
1095 for (c = 0; c < ARRAY_SIZE(detailed_attrs); c++) {
1096 pos = perf_evsel__new(detailed_attrs + c, c + attr_nr);
1097 if (pos == NULL)
1098 return -1;
1099 perf_evlist__add(evsel_list, pos);
1100 }
1101 attr_nr += c;
1102
1103 if (detailed_run < 2)
1104 return 0;
1105
1106 /* Append very detailed run extra attributes: */
1107 for (c = 0; c < ARRAY_SIZE(very_detailed_attrs); c++) {
1108 pos = perf_evsel__new(very_detailed_attrs + c, c + attr_nr);
1109 if (pos == NULL)
1110 return -1;
1111 perf_evlist__add(evsel_list, pos);
1112 }
1113
1114 if (detailed_run < 3)
1115 return 0;
1116
1117 /* Append very, very detailed run extra attributes: */
1118 for (c = 0; c < ARRAY_SIZE(very_very_detailed_attrs); c++) {
1119 pos = perf_evsel__new(very_very_detailed_attrs + c, c + attr_nr);
1120 if (pos == NULL)
1121 return -1;
1122 perf_evlist__add(evsel_list, pos);
1123 }
1124
1125
1126 return 0;
1127}
1128
677int cmd_stat(int argc, const char **argv, const char *prefix __used) 1129int cmd_stat(int argc, const char **argv, const char *prefix __used)
678{ 1130{
679 struct perf_evsel *pos; 1131 struct perf_evsel *pos;
@@ -719,17 +1171,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
719 usage_with_options(stat_usage, options); 1171 usage_with_options(stat_usage, options);
720 } 1172 }
721 1173
722 /* Set attrs and nr_counters if no event is selected and !null_run */ 1174 if (add_default_attributes())
723 if (!null_run && !evsel_list->nr_entries) { 1175 goto out;
724 size_t c;
725
726 for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) {
727 pos = perf_evsel__new(&default_attrs[c], c);
728 if (pos == NULL)
729 goto out;
730 perf_evlist__add(evsel_list, pos);
731 }
732 }
733 1176
734 if (target_pid != -1) 1177 if (target_pid != -1)
735 target_tid = target_pid; 1178 target_tid = target_pid;
@@ -773,6 +1216,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
773 for (run_idx = 0; run_idx < run_count; run_idx++) { 1216 for (run_idx = 0; run_idx < run_count; run_idx++) {
774 if (run_count != 1 && verbose) 1217 if (run_count != 1 && verbose)
775 fprintf(stderr, "[ perf stat: executing run #%d ... ]\n", run_idx + 1); 1218 fprintf(stderr, "[ perf stat: executing run #%d ... ]\n", run_idx + 1);
1219
1220 if (sync_run)
1221 sync();
1222
776 status = run_perf_stat(argc, argv); 1223 status = run_perf_stat(argc, argv);
777 } 1224 }
778 1225
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 11e3c8458362..2f9a337b182f 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -549,7 +549,7 @@ static int test__basic_mmap(void)
549 ++foo; 549 ++foo;
550 } 550 }
551 551
552 while ((event = perf_evlist__read_on_cpu(evlist, 0)) != NULL) { 552 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
553 struct perf_sample sample; 553 struct perf_sample sample;
554 554
555 if (event->header.type != PERF_RECORD_SAMPLE) { 555 if (event->header.type != PERF_RECORD_SAMPLE) {
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 7e3d6e310bf8..ebfc7cf5f63b 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -801,12 +801,12 @@ static void perf_event__process_sample(const union perf_event *event,
801 } 801 }
802} 802}
803 803
804static void perf_session__mmap_read_cpu(struct perf_session *self, int cpu) 804static void perf_session__mmap_read_idx(struct perf_session *self, int idx)
805{ 805{
806 struct perf_sample sample; 806 struct perf_sample sample;
807 union perf_event *event; 807 union perf_event *event;
808 808
809 while ((event = perf_evlist__read_on_cpu(top.evlist, cpu)) != NULL) { 809 while ((event = perf_evlist__mmap_read(top.evlist, idx)) != NULL) {
810 perf_session__parse_sample(self, event, &sample); 810 perf_session__parse_sample(self, event, &sample);
811 811
812 if (event->header.type == PERF_RECORD_SAMPLE) 812 if (event->header.type == PERF_RECORD_SAMPLE)
@@ -820,8 +820,8 @@ static void perf_session__mmap_read(struct perf_session *self)
820{ 820{
821 int i; 821 int i;
822 822
823 for (i = 0; i < top.evlist->cpus->nr; i++) 823 for (i = 0; i < top.evlist->nr_mmaps; i++)
824 perf_session__mmap_read_cpu(self, i); 824 perf_session__mmap_read_idx(self, i);
825} 825}
826 826
827static void start_counters(struct perf_evlist *evlist) 827static void start_counters(struct perf_evlist *evlist)
diff --git a/tools/perf/feature-tests.mak b/tools/perf/config/feature-tests.mak
index b041ca67a2cb..6170fd2531b5 100644
--- a/tools/perf/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -79,9 +79,15 @@ endef
79endif 79endif
80 80
81ifndef NO_LIBPYTHON 81ifndef NO_LIBPYTHON
82define SOURCE_PYTHON_VERSION
83#include <Python.h>
84#if PY_VERSION_HEX >= 0x03000000
85 #error
86#endif
87int main(void){}
88endef
82define SOURCE_PYTHON_EMBED 89define SOURCE_PYTHON_EMBED
83#include <Python.h> 90#include <Python.h>
84
85int main(void) 91int main(void)
86{ 92{
87 Py_Initialize(); 93 Py_Initialize();
@@ -120,11 +126,3 @@ int main(void)
120 return 0; 126 return 0;
121} 127}
122endef 128endef
123
124# try-cc
125# Usage: option = $(call try-cc, source-to-build, cc-options)
126try-cc = $(shell sh -c \
127 'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \
128 echo "$(1)" | \
129 $(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \
130 rm -f "$$TMP"')
diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak
new file mode 100644
index 000000000000..8046182a19eb
--- /dev/null
+++ b/tools/perf/config/utilities.mak
@@ -0,0 +1,188 @@
1# This allows us to work with the newline character:
2define newline
3
4
5endef
6newline := $(newline)
7
8# nl-escape
9#
10# Usage: escape = $(call nl-escape[,escape])
11#
12# This is used as the common way to specify
13# what should replace a newline when escaping
14# newlines; the default is a bizarre string.
15#
16nl-escape = $(or $(1),m822df3020w6a44id34bt574ctac44eb9f4n)
17
18# escape-nl
19#
20# Usage: escaped-text = $(call escape-nl,text[,escape])
21#
22# GNU make's $(shell ...) function converts to a
23# single space each newline character in the output
24# produced during the expansion; this may not be
25# desirable.
26#
27# The only solution is to change each newline into
28# something that won't be converted, so that the
29# information can be recovered later with
30# $(call unescape-nl...)
31#
32escape-nl = $(subst $(newline),$(call nl-escape,$(2)),$(1))
33
34# unescape-nl
35#
36# Usage: text = $(call unescape-nl,escaped-text[,escape])
37#
38# See escape-nl.
39#
40unescape-nl = $(subst $(call nl-escape,$(2)),$(newline),$(1))
41
42# shell-escape-nl
43#
44# Usage: $(shell some-command | $(call shell-escape-nl[,escape]))
45#
46# Use this to escape newlines from within a shell call;
47# the default escape is a bizarre string.
48#
49# NOTE: The escape is used directly as a string constant
50# in an `awk' program that is delimited by shell
51# single-quotes, so be wary of the characters
52# that are chosen.
53#
54define shell-escape-nl
55awk 'NR==1 {t=$$0} NR>1 {t=t "$(nl-escape)" $$0} END {printf t}'
56endef
57
58# shell-unescape-nl
59#
60# Usage: $(shell some-command | $(call shell-unescape-nl[,escape]))
61#
62# Use this to unescape newlines from within a shell call;
63# the default escape is a bizarre string.
64#
65# NOTE: The escape is used directly as an extended regular
66# expression constant in an `awk' program that is
67# delimited by shell single-quotes, so be wary
68# of the characters that are chosen.
69#
70# (The bash shell has a bug where `{gsub(...),...}' is
71# misinterpreted as a brace expansion; this can be
72# overcome by putting a space between `{' and `gsub').
73#
74define shell-unescape-nl
75awk 'NR==1 {t=$$0} NR>1 {t=t "\n" $$0} END { gsub(/$(nl-escape)/,"\n",t); printf t }'
76endef
77
78# escape-for-shell-sq
79#
80# Usage: embeddable-text = $(call escape-for-shell-sq,text)
81#
82# This function produces text that is suitable for
83# embedding in a shell string that is delimited by
84# single-quotes.
85#
86escape-for-shell-sq = $(subst ','\'',$(1))
87
88# shell-sq
89#
90# Usage: single-quoted-and-escaped-text = $(call shell-sq,text)
91#
92shell-sq = '$(escape-for-shell-sq)'
93
94# shell-wordify
95#
96# Usage: wordified-text = $(call shell-wordify,text)
97#
98# For instance:
99#
100# |define text
101# |hello
102# |world
103# |endef
104# |
105# |target:
106# | echo $(call shell-wordify,$(text))
107#
108# At least GNU make gets confused by expanding a newline
109# within the context of a command line of a makefile rule
110# (this is in constrast to a `$(shell ...)' function call,
111# which can handle it just fine).
112#
113# This function avoids the problem by producing a string
114# that works as a shell word, regardless of whether or
115# not it contains a newline.
116#
117# If the text to be wordified contains a newline, then
118# an intrictate shell command substitution is constructed
119# to render the text as a single line; when the shell
120# processes the resulting escaped text, it transforms
121# it into the original unescaped text.
122#
123# If the text does not contain a newline, then this function
124# produces the same results as the `$(shell-sq)' function.
125#
126shell-wordify = $(if $(findstring $(newline),$(1)),$(_sw-esc-nl),$(shell-sq))
127define _sw-esc-nl
128"$$(echo $(call escape-nl,$(shell-sq),$(2)) | $(call shell-unescape-nl,$(2)))"
129endef
130
131# is-absolute
132#
133# Usage: bool-value = $(call is-absolute,path)
134#
135is-absolute = $(shell echo $(shell-sq) | grep ^/ -q && echo y)
136
137# lookup
138#
139# Usage: absolute-executable-path-or-empty = $(call lookup,path)
140#
141# (It's necessary to use `sh -c' because GNU make messes up by
142# trying too hard and getting things wrong).
143#
144lookup = $(call unescape-nl,$(shell sh -c $(_l-sh)))
145_l-sh = $(call shell-sq,command -v $(shell-sq) | $(call shell-escape-nl,))
146
147# is-executable
148#
149# Usage: bool-value = $(call is-executable,path)
150#
151# (It's necessary to use `sh -c' because GNU make messes up by
152# trying too hard and getting things wrong).
153#
154is-executable = $(call _is-executable-helper,$(shell-sq))
155_is-executable-helper = $(shell sh -c $(_is-executable-sh))
156_is-executable-sh = $(call shell-sq,test -f $(1) -a -x $(1) && echo y)
157
158# get-executable
159#
160# Usage: absolute-executable-path-or-empty = $(call get-executable,path)
161#
162# The goal is to get an absolute path for an executable;
163# the `command -v' is defined by POSIX, but it's not
164# necessarily very portable, so it's only used if
165# relative path resolution is requested, as determined
166# by the presence of a leading `/'.
167#
168get-executable = $(if $(1),$(if $(is-absolute),$(_ge-abspath),$(lookup)))
169_ge-abspath = $(if $(is-executable),$(1))
170
171# get-supplied-or-default-executable
172#
173# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default)
174#
175define get-executable-or-default
176$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
177endef
178_ge_attempt = $(or $(get-executable),$(_gea_warn),$(call _gea_err,$(2)))
179_gea_warn = $(warning The path '$(1)' is not executable.)
180_gea_err = $(if $(1),$(error Please set '$(1)' appropriately))
181
182# try-cc
183# Usage: option = $(call try-cc, source-to-build, cc-options)
184try-cc = $(shell sh -c \
185 'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \
186 echo "$(1)" | \
187 $(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \
188 rm -f "$$TMP"')
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 45da8d186b49..23eb22b05d27 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -166,11 +166,11 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
166 return NULL; 166 return NULL;
167} 167}
168 168
169union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu) 169union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
170{ 170{
171 /* XXX Move this to perf.c, making it generally available */ 171 /* XXX Move this to perf.c, making it generally available */
172 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 172 unsigned int page_size = sysconf(_SC_PAGE_SIZE);
173 struct perf_mmap *md = &evlist->mmap[cpu]; 173 struct perf_mmap *md = &evlist->mmap[idx];
174 unsigned int head = perf_mmap__read_head(md); 174 unsigned int head = perf_mmap__read_head(md);
175 unsigned int old = md->prev; 175 unsigned int old = md->prev;
176 unsigned char *data = md->base + page_size; 176 unsigned char *data = md->base + page_size;
@@ -235,31 +235,37 @@ union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu)
235 235
236void perf_evlist__munmap(struct perf_evlist *evlist) 236void perf_evlist__munmap(struct perf_evlist *evlist)
237{ 237{
238 int cpu; 238 int i;
239 239
240 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { 240 for (i = 0; i < evlist->nr_mmaps; i++) {
241 if (evlist->mmap[cpu].base != NULL) { 241 if (evlist->mmap[i].base != NULL) {
242 munmap(evlist->mmap[cpu].base, evlist->mmap_len); 242 munmap(evlist->mmap[i].base, evlist->mmap_len);
243 evlist->mmap[cpu].base = NULL; 243 evlist->mmap[i].base = NULL;
244 } 244 }
245 } 245 }
246
247 free(evlist->mmap);
248 evlist->mmap = NULL;
246} 249}
247 250
248int perf_evlist__alloc_mmap(struct perf_evlist *evlist) 251int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
249{ 252{
250 evlist->mmap = zalloc(evlist->cpus->nr * sizeof(struct perf_mmap)); 253 evlist->nr_mmaps = evlist->cpus->nr;
254 if (evlist->cpus->map[0] == -1)
255 evlist->nr_mmaps = evlist->threads->nr;
256 evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
251 return evlist->mmap != NULL ? 0 : -ENOMEM; 257 return evlist->mmap != NULL ? 0 : -ENOMEM;
252} 258}
253 259
254static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel, 260static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel,
255 int cpu, int prot, int mask, int fd) 261 int idx, int prot, int mask, int fd)
256{ 262{
257 evlist->mmap[cpu].prev = 0; 263 evlist->mmap[idx].prev = 0;
258 evlist->mmap[cpu].mask = mask; 264 evlist->mmap[idx].mask = mask;
259 evlist->mmap[cpu].base = mmap(NULL, evlist->mmap_len, prot, 265 evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
260 MAP_SHARED, fd, 0); 266 MAP_SHARED, fd, 0);
261 if (evlist->mmap[cpu].base == MAP_FAILED) { 267 if (evlist->mmap[idx].base == MAP_FAILED) {
262 if (evlist->cpus->map[cpu] == -1 && evsel->attr.inherit) 268 if (evlist->cpus->map[idx] == -1 && evsel->attr.inherit)
263 ui__warning("Inherit is not allowed on per-task " 269 ui__warning("Inherit is not allowed on per-task "
264 "events using mmap.\n"); 270 "events using mmap.\n");
265 return -1; 271 return -1;
@@ -269,6 +275,86 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *ev
269 return 0; 275 return 0;
270} 276}
271 277
278static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask)
279{
280 struct perf_evsel *evsel;
281 int cpu, thread;
282
283 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
284 int output = -1;
285
286 for (thread = 0; thread < evlist->threads->nr; thread++) {
287 list_for_each_entry(evsel, &evlist->entries, node) {
288 int fd = FD(evsel, cpu, thread);
289
290 if (output == -1) {
291 output = fd;
292 if (__perf_evlist__mmap(evlist, evsel, cpu,
293 prot, mask, output) < 0)
294 goto out_unmap;
295 } else {
296 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
297 goto out_unmap;
298 }
299
300 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
301 perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
302 goto out_unmap;
303 }
304 }
305 }
306
307 return 0;
308
309out_unmap:
310 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
311 if (evlist->mmap[cpu].base != NULL) {
312 munmap(evlist->mmap[cpu].base, evlist->mmap_len);
313 evlist->mmap[cpu].base = NULL;
314 }
315 }
316 return -1;
317}
318
319static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask)
320{
321 struct perf_evsel *evsel;
322 int thread;
323
324 for (thread = 0; thread < evlist->threads->nr; thread++) {
325 int output = -1;
326
327 list_for_each_entry(evsel, &evlist->entries, node) {
328 int fd = FD(evsel, 0, thread);
329
330 if (output == -1) {
331 output = fd;
332 if (__perf_evlist__mmap(evlist, evsel, thread,
333 prot, mask, output) < 0)
334 goto out_unmap;
335 } else {
336 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
337 goto out_unmap;
338 }
339
340 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
341 perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0)
342 goto out_unmap;
343 }
344 }
345
346 return 0;
347
348out_unmap:
349 for (thread = 0; thread < evlist->threads->nr; thread++) {
350 if (evlist->mmap[thread].base != NULL) {
351 munmap(evlist->mmap[thread].base, evlist->mmap_len);
352 evlist->mmap[thread].base = NULL;
353 }
354 }
355 return -1;
356}
357
272/** perf_evlist__mmap - Create per cpu maps to receive events 358/** perf_evlist__mmap - Create per cpu maps to receive events
273 * 359 *
274 * @evlist - list of events 360 * @evlist - list of events
@@ -287,11 +373,11 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *ev
287int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) 373int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite)
288{ 374{
289 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 375 unsigned int page_size = sysconf(_SC_PAGE_SIZE);
290 int mask = pages * page_size - 1, cpu; 376 int mask = pages * page_size - 1;
291 struct perf_evsel *first_evsel, *evsel; 377 struct perf_evsel *evsel;
292 const struct cpu_map *cpus = evlist->cpus; 378 const struct cpu_map *cpus = evlist->cpus;
293 const struct thread_map *threads = evlist->threads; 379 const struct thread_map *threads = evlist->threads;
294 int thread, prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); 380 int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE);
295 381
296 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) 382 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
297 return -ENOMEM; 383 return -ENOMEM;
@@ -301,43 +387,18 @@ int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite)
301 387
302 evlist->overwrite = overwrite; 388 evlist->overwrite = overwrite;
303 evlist->mmap_len = (pages + 1) * page_size; 389 evlist->mmap_len = (pages + 1) * page_size;
304 first_evsel = list_entry(evlist->entries.next, struct perf_evsel, node);
305 390
306 list_for_each_entry(evsel, &evlist->entries, node) { 391 list_for_each_entry(evsel, &evlist->entries, node) {
307 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 392 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
308 evsel->sample_id == NULL && 393 evsel->sample_id == NULL &&
309 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0) 394 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0)
310 return -ENOMEM; 395 return -ENOMEM;
311
312 for (cpu = 0; cpu < cpus->nr; cpu++) {
313 for (thread = 0; thread < threads->nr; thread++) {
314 int fd = FD(evsel, cpu, thread);
315
316 if (evsel->idx || thread) {
317 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT,
318 FD(first_evsel, cpu, 0)) != 0)
319 goto out_unmap;
320 } else if (__perf_evlist__mmap(evlist, evsel, cpu,
321 prot, mask, fd) < 0)
322 goto out_unmap;
323
324 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
325 perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
326 goto out_unmap;
327 }
328 }
329 } 396 }
330 397
331 return 0; 398 if (evlist->cpus->map[0] == -1)
399 return perf_evlist__mmap_per_thread(evlist, prot, mask);
332 400
333out_unmap: 401 return perf_evlist__mmap_per_cpu(evlist, prot, mask);
334 for (cpu = 0; cpu < cpus->nr; cpu++) {
335 if (evlist->mmap[cpu].base != NULL) {
336 munmap(evlist->mmap[cpu].base, evlist->mmap_len);
337 evlist->mmap[cpu].base = NULL;
338 }
339 }
340 return -1;
341} 402}
342 403
343int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, 404int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
@@ -348,7 +409,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
348 if (evlist->threads == NULL) 409 if (evlist->threads == NULL)
349 return -1; 410 return -1;
350 411
351 if (target_tid != -1) 412 if (cpu_list == NULL && target_tid != -1)
352 evlist->cpus = cpu_map__dummy_new(); 413 evlist->cpus = cpu_map__dummy_new();
353 else 414 else
354 evlist->cpus = cpu_map__new(cpu_list); 415 evlist->cpus = cpu_map__new(cpu_list);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 8b1cb7a4c5f1..7109d7add14e 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -17,6 +17,7 @@ struct perf_evlist {
17 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; 17 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
18 int nr_entries; 18 int nr_entries;
19 int nr_fds; 19 int nr_fds;
20 int nr_mmaps;
20 int mmap_len; 21 int mmap_len;
21 bool overwrite; 22 bool overwrite;
22 union perf_event event_copy; 23 union perf_event event_copy;
@@ -46,7 +47,7 @@ void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd);
46 47
47struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); 48struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
48 49
49union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *self, int cpu); 50union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
50 51
51int perf_evlist__alloc_mmap(struct perf_evlist *evlist); 52int perf_evlist__alloc_mmap(struct perf_evlist *evlist);
52int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite); 53int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite);
diff --git a/tools/perf/util/include/asm/alternative-asm.h b/tools/perf/util/include/asm/alternative-asm.h
new file mode 100644
index 000000000000..6789d788d494
--- /dev/null
+++ b/tools/perf/util/include/asm/alternative-asm.h
@@ -0,0 +1,8 @@
1#ifndef _PERF_ASM_ALTERNATIVE_ASM_H
2#define _PERF_ASM_ALTERNATIVE_ASM_H
3
4/* Just disable it so we can build arch/x86/lib/memcpy_64.S for perf bench: */
5
6#define altinstruction_entry #
7
8#endif
diff --git a/tools/perf/util/include/linux/list.h b/tools/perf/util/include/linux/list.h
index 356c7e467b83..99358d61e9a5 100644
--- a/tools/perf/util/include/linux/list.h
+++ b/tools/perf/util/include/linux/list.h
@@ -23,5 +23,5 @@ static inline void list_del_range(struct list_head *begin,
23 * @head: the head for your list. 23 * @head: the head for your list.
24 */ 24 */
25#define list_for_each_from(pos, head) \ 25#define list_for_each_from(pos, head) \
26 for (; prefetch(pos->next), pos != (head); pos = pos->next) 26 for (; pos != (head); pos = pos->next)
27#endif 27#endif
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 952b4ae3d954..41982c373faf 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -31,34 +31,36 @@ char debugfs_path[MAXPATHLEN];
31#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 31#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
32 32
33static struct event_symbol event_symbols[] = { 33static struct event_symbol event_symbols[] = {
34 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, 34 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" },
35 { CHW(INSTRUCTIONS), "instructions", "" }, 35 { CHW(STALLED_CYCLES_FRONTEND), "stalled-cycles-frontend", "idle-cycles-frontend" },
36 { CHW(CACHE_REFERENCES), "cache-references", "" }, 36 { CHW(STALLED_CYCLES_BACKEND), "stalled-cycles-backend", "idle-cycles-backend" },
37 { CHW(CACHE_MISSES), "cache-misses", "" }, 37 { CHW(INSTRUCTIONS), "instructions", "" },
38 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, 38 { CHW(CACHE_REFERENCES), "cache-references", "" },
39 { CHW(BRANCH_MISSES), "branch-misses", "" }, 39 { CHW(CACHE_MISSES), "cache-misses", "" },
40 { CHW(BUS_CYCLES), "bus-cycles", "" }, 40 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" },
41 41 { CHW(BRANCH_MISSES), "branch-misses", "" },
42 { CSW(CPU_CLOCK), "cpu-clock", "" }, 42 { CHW(BUS_CYCLES), "bus-cycles", "" },
43 { CSW(TASK_CLOCK), "task-clock", "" }, 43
44 { CSW(PAGE_FAULTS), "page-faults", "faults" }, 44 { CSW(CPU_CLOCK), "cpu-clock", "" },
45 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, 45 { CSW(TASK_CLOCK), "task-clock", "" },
46 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, 46 { CSW(PAGE_FAULTS), "page-faults", "faults" },
47 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, 47 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" },
48 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 48 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" },
49 { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" }, 49 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" },
50 { CSW(EMULATION_FAULTS), "emulation-faults", "" }, 50 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" },
51 { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" },
52 { CSW(EMULATION_FAULTS), "emulation-faults", "" },
51}; 53};
52 54
53#define __PERF_EVENT_FIELD(config, name) \ 55#define __PERF_EVENT_FIELD(config, name) \
54 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) 56 ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
55 57
56#define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) 58#define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW)
57#define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) 59#define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG)
58#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 60#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE)
59#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 61#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT)
60 62
61static const char *hw_event_names[] = { 63static const char *hw_event_names[PERF_COUNT_HW_MAX] = {
62 "cycles", 64 "cycles",
63 "instructions", 65 "instructions",
64 "cache-references", 66 "cache-references",
@@ -66,11 +68,13 @@ static const char *hw_event_names[] = {
66 "branches", 68 "branches",
67 "branch-misses", 69 "branch-misses",
68 "bus-cycles", 70 "bus-cycles",
71 "stalled-cycles-frontend",
72 "stalled-cycles-backend",
69}; 73};
70 74
71static const char *sw_event_names[] = { 75static const char *sw_event_names[PERF_COUNT_SW_MAX] = {
72 "cpu-clock-msecs", 76 "cpu-clock",
73 "task-clock-msecs", 77 "task-clock",
74 "page-faults", 78 "page-faults",
75 "context-switches", 79 "context-switches",
76 "CPU-migrations", 80 "CPU-migrations",
@@ -307,7 +311,7 @@ const char *__event_name(int type, u64 config)
307 311
308 switch (type) { 312 switch (type) {
309 case PERF_TYPE_HARDWARE: 313 case PERF_TYPE_HARDWARE:
310 if (config < PERF_COUNT_HW_MAX) 314 if (config < PERF_COUNT_HW_MAX && hw_event_names[config])
311 return hw_event_names[config]; 315 return hw_event_names[config];
312 return "unknown-hardware"; 316 return "unknown-hardware";
313 317
@@ -333,7 +337,7 @@ const char *__event_name(int type, u64 config)
333 } 337 }
334 338
335 case PERF_TYPE_SOFTWARE: 339 case PERF_TYPE_SOFTWARE:
336 if (config < PERF_COUNT_SW_MAX) 340 if (config < PERF_COUNT_SW_MAX && sw_event_names[config])
337 return sw_event_names[config]; 341 return sw_event_names[config];
338 return "unknown-software"; 342 return "unknown-software";
339 343
@@ -648,13 +652,15 @@ static int check_events(const char *str, unsigned int i)
648 int n; 652 int n;
649 653
650 n = strlen(event_symbols[i].symbol); 654 n = strlen(event_symbols[i].symbol);
651 if (!strncmp(str, event_symbols[i].symbol, n)) 655 if (!strncasecmp(str, event_symbols[i].symbol, n))
652 return n; 656 return n;
653 657
654 n = strlen(event_symbols[i].alias); 658 n = strlen(event_symbols[i].alias);
655 if (n) 659 if (n) {
656 if (!strncmp(str, event_symbols[i].alias, n)) 660 if (!strncasecmp(str, event_symbols[i].alias, n))
657 return n; 661 return n;
662 }
663
658 return 0; 664 return 0;
659} 665}
660 666
@@ -718,15 +724,22 @@ parse_numeric_event(const char **strp, struct perf_event_attr *attr)
718 return EVT_FAILED; 724 return EVT_FAILED;
719} 725}
720 726
721static enum event_result 727static int
722parse_event_modifier(const char **strp, struct perf_event_attr *attr) 728parse_event_modifier(const char **strp, struct perf_event_attr *attr)
723{ 729{
724 const char *str = *strp; 730 const char *str = *strp;
725 int exclude = 0; 731 int exclude = 0;
726 int eu = 0, ek = 0, eh = 0, precise = 0; 732 int eu = 0, ek = 0, eh = 0, precise = 0;
727 733
728 if (*str++ != ':') 734 if (!*str)
735 return 0;
736
737 if (*str == ',')
729 return 0; 738 return 0;
739
740 if (*str++ != ':')
741 return -1;
742
730 while (*str) { 743 while (*str) {
731 if (*str == 'u') { 744 if (*str == 'u') {
732 if (!exclude) 745 if (!exclude)
@@ -747,14 +760,16 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr)
747 760
748 ++str; 761 ++str;
749 } 762 }
750 if (str >= *strp + 2) { 763 if (str < *strp + 2)
751 *strp = str; 764 return -1;
752 attr->exclude_user = eu; 765
753 attr->exclude_kernel = ek; 766 *strp = str;
754 attr->exclude_hv = eh; 767
755 attr->precise_ip = precise; 768 attr->exclude_user = eu;
756 return 1; 769 attr->exclude_kernel = ek;
757 } 770 attr->exclude_hv = eh;
771 attr->precise_ip = precise;
772
758 return 0; 773 return 0;
759} 774}
760 775
@@ -797,7 +812,12 @@ parse_event_symbols(const struct option *opt, const char **str,
797 return EVT_FAILED; 812 return EVT_FAILED;
798 813
799modifier: 814modifier:
800 parse_event_modifier(str, attr); 815 if (parse_event_modifier(str, attr) < 0) {
816 fprintf(stderr, "invalid event modifier: '%s'\n", *str);
817 fprintf(stderr, "Run 'perf list' for a list of valid events and modifiers\n");
818
819 return EVT_FAILED;
820 }
801 821
802 return ret; 822 return ret;
803} 823}
@@ -912,7 +932,7 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
912 932
913 snprintf(evt_path, MAXPATHLEN, "%s:%s", 933 snprintf(evt_path, MAXPATHLEN, "%s:%s",
914 sys_dirent.d_name, evt_dirent.d_name); 934 sys_dirent.d_name, evt_dirent.d_name);
915 printf(" %-42s [%s]\n", evt_path, 935 printf(" %-50s [%s]\n", evt_path,
916 event_type_descriptors[PERF_TYPE_TRACEPOINT]); 936 event_type_descriptors[PERF_TYPE_TRACEPOINT]);
917 } 937 }
918 closedir(evt_dir); 938 closedir(evt_dir);
@@ -977,7 +997,7 @@ void print_events_type(u8 type)
977 else 997 else
978 snprintf(name, sizeof(name), "%s", syms->symbol); 998 snprintf(name, sizeof(name), "%s", syms->symbol);
979 999
980 printf(" %-42s [%s]\n", name, 1000 printf(" %-50s [%s]\n", name,
981 event_type_descriptors[type]); 1001 event_type_descriptors[type]);
982 } 1002 }
983} 1003}
@@ -995,11 +1015,10 @@ int print_hwcache_events(const char *event_glob)
995 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 1015 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
996 char *name = event_cache_name(type, op, i); 1016 char *name = event_cache_name(type, op, i);
997 1017
998 if (event_glob != NULL && 1018 if (event_glob != NULL && !strglobmatch(name, event_glob))
999 !strglobmatch(name, event_glob))
1000 continue; 1019 continue;
1001 1020
1002 printf(" %-42s [%s]\n", name, 1021 printf(" %-50s [%s]\n", name,
1003 event_type_descriptors[PERF_TYPE_HW_CACHE]); 1022 event_type_descriptors[PERF_TYPE_HW_CACHE]);
1004 ++printed; 1023 ++printed;
1005 } 1024 }
@@ -1009,14 +1028,16 @@ int print_hwcache_events(const char *event_glob)
1009 return printed; 1028 return printed;
1010} 1029}
1011 1030
1031#define MAX_NAME_LEN 100
1032
1012/* 1033/*
1013 * Print the help text for the event symbols: 1034 * Print the help text for the event symbols:
1014 */ 1035 */
1015void print_events(const char *event_glob) 1036void print_events(const char *event_glob)
1016{ 1037{
1017 struct event_symbol *syms = event_symbols;
1018 unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; 1038 unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0;
1019 char name[40]; 1039 struct event_symbol *syms = event_symbols;
1040 char name[MAX_NAME_LEN];
1020 1041
1021 printf("\n"); 1042 printf("\n");
1022 printf("List of pre-defined events (to be used in -e):\n"); 1043 printf("List of pre-defined events (to be used in -e):\n");
@@ -1036,10 +1057,10 @@ void print_events(const char *event_glob)
1036 continue; 1057 continue;
1037 1058
1038 if (strlen(syms->alias)) 1059 if (strlen(syms->alias))
1039 sprintf(name, "%s OR %s", syms->symbol, syms->alias); 1060 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
1040 else 1061 else
1041 strcpy(name, syms->symbol); 1062 strncpy(name, syms->symbol, MAX_NAME_LEN);
1042 printf(" %-42s [%s]\n", name, 1063 printf(" %-50s [%s]\n", name,
1043 event_type_descriptors[type]); 1064 event_type_descriptors[type]);
1044 1065
1045 prev_type = type; 1066 prev_type = type;
@@ -1056,12 +1077,12 @@ void print_events(const char *event_glob)
1056 return; 1077 return;
1057 1078
1058 printf("\n"); 1079 printf("\n");
1059 printf(" %-42s [%s]\n", 1080 printf(" %-50s [%s]\n",
1060 "rNNN (see 'perf list --help' on how to encode it)", 1081 "rNNN (see 'perf list --help' on how to encode it)",
1061 event_type_descriptors[PERF_TYPE_RAW]); 1082 event_type_descriptors[PERF_TYPE_RAW]);
1062 printf("\n"); 1083 printf("\n");
1063 1084
1064 printf(" %-42s [%s]\n", 1085 printf(" %-50s [%s]\n",
1065 "mem:<addr>[:access]", 1086 "mem:<addr>[:access]",
1066 event_type_descriptors[PERF_TYPE_BREAKPOINT]); 1087 event_type_descriptors[PERF_TYPE_BREAKPOINT]);
1067 printf("\n"); 1088 printf("\n");
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index b7c85ce466a1..3b9d0b800d5c 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1471,6 +1471,38 @@ static int find_probe_point_by_func(struct probe_finder *pf)
1471 return _param.retval; 1471 return _param.retval;
1472} 1472}
1473 1473
1474struct pubname_callback_param {
1475 char *function;
1476 char *file;
1477 Dwarf_Die *cu_die;
1478 Dwarf_Die *sp_die;
1479 int found;
1480};
1481
1482static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
1483{
1484 struct pubname_callback_param *param = data;
1485
1486 if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
1487 if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
1488 return DWARF_CB_OK;
1489
1490 if (die_compare_name(param->sp_die, param->function)) {
1491 if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
1492 return DWARF_CB_OK;
1493
1494 if (param->file &&
1495 strtailcmp(param->file, dwarf_decl_file(param->sp_die)))
1496 return DWARF_CB_OK;
1497
1498 param->found = 1;
1499 return DWARF_CB_ABORT;
1500 }
1501 }
1502
1503 return DWARF_CB_OK;
1504}
1505
1474/* Find probe points from debuginfo */ 1506/* Find probe points from debuginfo */
1475static int find_probes(int fd, struct probe_finder *pf) 1507static int find_probes(int fd, struct probe_finder *pf)
1476{ 1508{
@@ -1498,6 +1530,28 @@ static int find_probes(int fd, struct probe_finder *pf)
1498 1530
1499 off = 0; 1531 off = 0;
1500 line_list__init(&pf->lcache); 1532 line_list__init(&pf->lcache);
1533
1534 /* Fastpath: lookup by function name from .debug_pubnames section */
1535 if (pp->function) {
1536 struct pubname_callback_param pubname_param = {
1537 .function = pp->function,
1538 .file = pp->file,
1539 .cu_die = &pf->cu_die,
1540 .sp_die = &pf->sp_die,
1541 .found = 0,
1542 };
1543 struct dwarf_callback_param probe_param = {
1544 .data = pf,
1545 };
1546
1547 dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
1548 if (pubname_param.found) {
1549 ret = probe_point_search_cb(&pf->sp_die, &probe_param);
1550 if (ret)
1551 goto found;
1552 }
1553 }
1554
1501 /* Loop on CUs (Compilation Unit) */ 1555 /* Loop on CUs (Compilation Unit) */
1502 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) { 1556 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1503 /* Get the DIE(Debugging Information Entry) of this CU */ 1557 /* Get the DIE(Debugging Information Entry) of this CU */
@@ -1525,6 +1579,8 @@ static int find_probes(int fd, struct probe_finder *pf)
1525 } 1579 }
1526 off = noff; 1580 off = noff;
1527 } 1581 }
1582
1583found:
1528 line_list__free(&pf->lcache); 1584 line_list__free(&pf->lcache);
1529 if (dwfl) 1585 if (dwfl)
1530 dwfl_end(dwfl); 1586 dwfl_end(dwfl);
@@ -1946,6 +2002,22 @@ int find_line_range(int fd, struct line_range *lr)
1946 return -EBADF; 2002 return -EBADF;
1947 } 2003 }
1948 2004
2005 /* Fastpath: lookup by function name from .debug_pubnames section */
2006 if (lr->function) {
2007 struct pubname_callback_param pubname_param = {
2008 .function = lr->function, .file = lr->file,
2009 .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
2010 struct dwarf_callback_param line_range_param = {
2011 .data = (void *)&lf, .retval = 0};
2012
2013 dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
2014 if (pubname_param.found) {
2015 line_range_search_cb(&lf.sp_die, &line_range_param);
2016 if (lf.found)
2017 goto found;
2018 }
2019 }
2020
1949 /* Loop on CUs (Compilation Unit) */ 2021 /* Loop on CUs (Compilation Unit) */
1950 while (!lf.found && ret >= 0) { 2022 while (!lf.found && ret >= 0) {
1951 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0) 2023 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
@@ -1974,6 +2046,7 @@ int find_line_range(int fd, struct line_range *lr)
1974 off = noff; 2046 off = noff;
1975 } 2047 }
1976 2048
2049found:
1977 /* Store comp_dir */ 2050 /* Store comp_dir */
1978 if (lf.found) { 2051 if (lf.found) {
1979 comp_dir = cu_get_comp_dir(&lf.cu_die); 2052 comp_dir = cu_get_comp_dir(&lf.cu_die);
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index beaefc3c1223..605730a366db 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -49,6 +49,7 @@ struct probe_finder {
49 Dwarf_Addr addr; /* Address */ 49 Dwarf_Addr addr; /* Address */
50 const char *fname; /* Real file name */ 50 const char *fname; /* Real file name */
51 Dwarf_Die cu_die; /* Current CU */ 51 Dwarf_Die cu_die; /* Current CU */
52 Dwarf_Die sp_die;
52 struct list_head lcache; /* Line cache for lazy match */ 53 struct list_head lcache; /* Line cache for lazy match */
53 54
54 /* For variable searching */ 55 /* For variable searching */
@@ -83,6 +84,7 @@ struct line_finder {
83 int lno_s; /* Start line number */ 84 int lno_s; /* Start line number */
84 int lno_e; /* End line number */ 85 int lno_e; /* End line number */
85 Dwarf_Die cu_die; /* Current CU */ 86 Dwarf_Die cu_die; /* Current CU */
87 Dwarf_Die sp_die;
86 int found; 88 int found;
87}; 89};
88 90
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index f5e38451fdc5..b5c7d818001c 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -680,7 +680,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
680 &cpu, &sample_id_all)) 680 &cpu, &sample_id_all))
681 return NULL; 681 return NULL;
682 682
683 event = perf_evlist__read_on_cpu(evlist, cpu); 683 event = perf_evlist__mmap_read(evlist, cpu);
684 if (event != NULL) { 684 if (event != NULL) {
685 struct perf_evsel *first; 685 struct perf_evsel *first;
686 PyObject *pyevent = pyrf_event__new(event); 686 PyObject *pyevent = pyrf_event__new(event);
@@ -810,6 +810,9 @@ static struct {
810 { "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS }, 810 { "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS },
811 { "COUNT_HW_CACHE_RESULT_MISS", PERF_COUNT_HW_CACHE_RESULT_MISS }, 811 { "COUNT_HW_CACHE_RESULT_MISS", PERF_COUNT_HW_CACHE_RESULT_MISS },
812 812
813 { "COUNT_HW_STALLED_CYCLES_FRONTEND", PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
814 { "COUNT_HW_STALLED_CYCLES_BACKEND", PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
815
813 { "COUNT_SW_CPU_CLOCK", PERF_COUNT_SW_CPU_CLOCK }, 816 { "COUNT_SW_CPU_CLOCK", PERF_COUNT_SW_CPU_CLOCK },
814 { "COUNT_SW_TASK_CLOCK", PERF_COUNT_SW_TASK_CLOCK }, 817 { "COUNT_SW_TASK_CLOCK", PERF_COUNT_SW_TASK_CLOCK },
815 { "COUNT_SW_PAGE_FAULTS", PERF_COUNT_SW_PAGE_FAULTS }, 818 { "COUNT_SW_PAGE_FAULTS", PERF_COUNT_SW_PAGE_FAULTS },
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index caa224522fea..fff66741f18d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1156,6 +1156,18 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
1156 return ret; 1156 return ret;
1157} 1157}
1158 1158
1159struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
1160 unsigned int type)
1161{
1162 struct perf_evsel *pos;
1163
1164 list_for_each_entry(pos, &session->evlist->entries, node) {
1165 if (pos->attr.type == type)
1166 return pos;
1167 }
1168 return NULL;
1169}
1170
1159void perf_session__print_symbols(union perf_event *event, 1171void perf_session__print_symbols(union perf_event *event,
1160 struct perf_sample *sample, 1172 struct perf_sample *sample,
1161 struct perf_session *session) 1173 struct perf_session *session)
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 1ac481fc1100..8daaa2d15396 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -162,6 +162,9 @@ static inline int perf_session__parse_sample(struct perf_session *session,
162 session->sample_id_all, sample); 162 session->sample_id_all, sample);
163} 163}
164 164
165struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
166 unsigned int type);
167
165void perf_session__print_symbols(union perf_event *event, 168void perf_session__print_symbols(union perf_event *event,
166 struct perf_sample *sample, 169 struct perf_sample *sample,
167 struct perf_session *session); 170 struct perf_session *session);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index f06c10f092ba..516876dfbe52 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -31,13 +31,13 @@
31#define NT_GNU_BUILD_ID 3 31#define NT_GNU_BUILD_ID 3
32#endif 32#endif
33 33
34static bool dso__build_id_equal(const struct dso *self, u8 *build_id); 34static bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
35static int elf_read_build_id(Elf *elf, void *bf, size_t size); 35static int elf_read_build_id(Elf *elf, void *bf, size_t size);
36static void dsos__add(struct list_head *head, struct dso *dso); 36static void dsos__add(struct list_head *head, struct dso *dso);
37static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 37static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
38static int dso__load_kernel_sym(struct dso *self, struct map *map, 38static int dso__load_kernel_sym(struct dso *dso, struct map *map,
39 symbol_filter_t filter); 39 symbol_filter_t filter);
40static int dso__load_guest_kernel_sym(struct dso *self, struct map *map, 40static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
41 symbol_filter_t filter); 41 symbol_filter_t filter);
42static int vmlinux_path__nr_entries; 42static int vmlinux_path__nr_entries;
43static char **vmlinux_path; 43static char **vmlinux_path;
@@ -49,27 +49,27 @@ struct symbol_conf symbol_conf = {
49 .symfs = "", 49 .symfs = "",
50}; 50};
51 51
52int dso__name_len(const struct dso *self) 52int dso__name_len(const struct dso *dso)
53{ 53{
54 if (verbose) 54 if (verbose)
55 return self->long_name_len; 55 return dso->long_name_len;
56 56
57 return self->short_name_len; 57 return dso->short_name_len;
58} 58}
59 59
60bool dso__loaded(const struct dso *self, enum map_type type) 60bool dso__loaded(const struct dso *dso, enum map_type type)
61{ 61{
62 return self->loaded & (1 << type); 62 return dso->loaded & (1 << type);
63} 63}
64 64
65bool dso__sorted_by_name(const struct dso *self, enum map_type type) 65bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
66{ 66{
67 return self->sorted_by_name & (1 << type); 67 return dso->sorted_by_name & (1 << type);
68} 68}
69 69
70static void dso__set_sorted_by_name(struct dso *self, enum map_type type) 70static void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
71{ 71{
72 self->sorted_by_name |= (1 << type); 72 dso->sorted_by_name |= (1 << type);
73} 73}
74 74
75bool symbol_type__is_a(char symbol_type, enum map_type map_type) 75bool symbol_type__is_a(char symbol_type, enum map_type map_type)
@@ -84,9 +84,9 @@ bool symbol_type__is_a(char symbol_type, enum map_type map_type)
84 } 84 }
85} 85}
86 86
87static void symbols__fixup_end(struct rb_root *self) 87static void symbols__fixup_end(struct rb_root *symbols)
88{ 88{
89 struct rb_node *nd, *prevnd = rb_first(self); 89 struct rb_node *nd, *prevnd = rb_first(symbols);
90 struct symbol *curr, *prev; 90 struct symbol *curr, *prev;
91 91
92 if (prevnd == NULL) 92 if (prevnd == NULL)
@@ -107,10 +107,10 @@ static void symbols__fixup_end(struct rb_root *self)
107 curr->end = roundup(curr->start, 4096); 107 curr->end = roundup(curr->start, 4096);
108} 108}
109 109
110static void __map_groups__fixup_end(struct map_groups *self, enum map_type type) 110static void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
111{ 111{
112 struct map *prev, *curr; 112 struct map *prev, *curr;
113 struct rb_node *nd, *prevnd = rb_first(&self->maps[type]); 113 struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]);
114 114
115 if (prevnd == NULL) 115 if (prevnd == NULL)
116 return; 116 return;
@@ -130,128 +130,128 @@ static void __map_groups__fixup_end(struct map_groups *self, enum map_type type)
130 curr->end = ~0ULL; 130 curr->end = ~0ULL;
131} 131}
132 132
133static void map_groups__fixup_end(struct map_groups *self) 133static void map_groups__fixup_end(struct map_groups *mg)
134{ 134{
135 int i; 135 int i;
136 for (i = 0; i < MAP__NR_TYPES; ++i) 136 for (i = 0; i < MAP__NR_TYPES; ++i)
137 __map_groups__fixup_end(self, i); 137 __map_groups__fixup_end(mg, i);
138} 138}
139 139
140static struct symbol *symbol__new(u64 start, u64 len, u8 binding, 140static struct symbol *symbol__new(u64 start, u64 len, u8 binding,
141 const char *name) 141 const char *name)
142{ 142{
143 size_t namelen = strlen(name) + 1; 143 size_t namelen = strlen(name) + 1;
144 struct symbol *self = calloc(1, (symbol_conf.priv_size + 144 struct symbol *sym = calloc(1, (symbol_conf.priv_size +
145 sizeof(*self) + namelen)); 145 sizeof(*sym) + namelen));
146 if (self == NULL) 146 if (sym == NULL)
147 return NULL; 147 return NULL;
148 148
149 if (symbol_conf.priv_size) 149 if (symbol_conf.priv_size)
150 self = ((void *)self) + symbol_conf.priv_size; 150 sym = ((void *)sym) + symbol_conf.priv_size;
151
152 self->start = start;
153 self->end = len ? start + len - 1 : start;
154 self->binding = binding;
155 self->namelen = namelen - 1;
156 151
157 pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n", __func__, name, start, self->end); 152 sym->start = start;
153 sym->end = len ? start + len - 1 : start;
154 sym->binding = binding;
155 sym->namelen = namelen - 1;
158 156
159 memcpy(self->name, name, namelen); 157 pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n",
158 __func__, name, start, sym->end);
159 memcpy(sym->name, name, namelen);
160 160
161 return self; 161 return sym;
162} 162}
163 163
164void symbol__delete(struct symbol *self) 164void symbol__delete(struct symbol *sym)
165{ 165{
166 free(((void *)self) - symbol_conf.priv_size); 166 free(((void *)sym) - symbol_conf.priv_size);
167} 167}
168 168
169static size_t symbol__fprintf(struct symbol *self, FILE *fp) 169static size_t symbol__fprintf(struct symbol *sym, FILE *fp)
170{ 170{
171 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n", 171 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
172 self->start, self->end, 172 sym->start, sym->end,
173 self->binding == STB_GLOBAL ? 'g' : 173 sym->binding == STB_GLOBAL ? 'g' :
174 self->binding == STB_LOCAL ? 'l' : 'w', 174 sym->binding == STB_LOCAL ? 'l' : 'w',
175 self->name); 175 sym->name);
176} 176}
177 177
178void dso__set_long_name(struct dso *self, char *name) 178void dso__set_long_name(struct dso *dso, char *name)
179{ 179{
180 if (name == NULL) 180 if (name == NULL)
181 return; 181 return;
182 self->long_name = name; 182 dso->long_name = name;
183 self->long_name_len = strlen(name); 183 dso->long_name_len = strlen(name);
184} 184}
185 185
186static void dso__set_short_name(struct dso *self, const char *name) 186static void dso__set_short_name(struct dso *dso, const char *name)
187{ 187{
188 if (name == NULL) 188 if (name == NULL)
189 return; 189 return;
190 self->short_name = name; 190 dso->short_name = name;
191 self->short_name_len = strlen(name); 191 dso->short_name_len = strlen(name);
192} 192}
193 193
194static void dso__set_basename(struct dso *self) 194static void dso__set_basename(struct dso *dso)
195{ 195{
196 dso__set_short_name(self, basename(self->long_name)); 196 dso__set_short_name(dso, basename(dso->long_name));
197} 197}
198 198
199struct dso *dso__new(const char *name) 199struct dso *dso__new(const char *name)
200{ 200{
201 struct dso *self = calloc(1, sizeof(*self) + strlen(name) + 1); 201 struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
202 202
203 if (self != NULL) { 203 if (dso != NULL) {
204 int i; 204 int i;
205 strcpy(self->name, name); 205 strcpy(dso->name, name);
206 dso__set_long_name(self, self->name); 206 dso__set_long_name(dso, dso->name);
207 dso__set_short_name(self, self->name); 207 dso__set_short_name(dso, dso->name);
208 for (i = 0; i < MAP__NR_TYPES; ++i) 208 for (i = 0; i < MAP__NR_TYPES; ++i)
209 self->symbols[i] = self->symbol_names[i] = RB_ROOT; 209 dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
210 self->symtab_type = SYMTAB__NOT_FOUND; 210 dso->symtab_type = SYMTAB__NOT_FOUND;
211 self->loaded = 0; 211 dso->loaded = 0;
212 self->sorted_by_name = 0; 212 dso->sorted_by_name = 0;
213 self->has_build_id = 0; 213 dso->has_build_id = 0;
214 self->kernel = DSO_TYPE_USER; 214 dso->kernel = DSO_TYPE_USER;
215 INIT_LIST_HEAD(&self->node); 215 INIT_LIST_HEAD(&dso->node);
216 } 216 }
217 217
218 return self; 218 return dso;
219} 219}
220 220
221static void symbols__delete(struct rb_root *self) 221static void symbols__delete(struct rb_root *symbols)
222{ 222{
223 struct symbol *pos; 223 struct symbol *pos;
224 struct rb_node *next = rb_first(self); 224 struct rb_node *next = rb_first(symbols);
225 225
226 while (next) { 226 while (next) {
227 pos = rb_entry(next, struct symbol, rb_node); 227 pos = rb_entry(next, struct symbol, rb_node);
228 next = rb_next(&pos->rb_node); 228 next = rb_next(&pos->rb_node);
229 rb_erase(&pos->rb_node, self); 229 rb_erase(&pos->rb_node, symbols);
230 symbol__delete(pos); 230 symbol__delete(pos);
231 } 231 }
232} 232}
233 233
234void dso__delete(struct dso *self) 234void dso__delete(struct dso *dso)
235{ 235{
236 int i; 236 int i;
237 for (i = 0; i < MAP__NR_TYPES; ++i) 237 for (i = 0; i < MAP__NR_TYPES; ++i)
238 symbols__delete(&self->symbols[i]); 238 symbols__delete(&dso->symbols[i]);
239 if (self->sname_alloc) 239 if (dso->sname_alloc)
240 free((char *)self->short_name); 240 free((char *)dso->short_name);
241 if (self->lname_alloc) 241 if (dso->lname_alloc)
242 free(self->long_name); 242 free(dso->long_name);
243 free(self); 243 free(dso);
244} 244}
245 245
246void dso__set_build_id(struct dso *self, void *build_id) 246void dso__set_build_id(struct dso *dso, void *build_id)
247{ 247{
248 memcpy(self->build_id, build_id, sizeof(self->build_id)); 248 memcpy(dso->build_id, build_id, sizeof(dso->build_id));
249 self->has_build_id = 1; 249 dso->has_build_id = 1;
250} 250}
251 251
252static void symbols__insert(struct rb_root *self, struct symbol *sym) 252static void symbols__insert(struct rb_root *symbols, struct symbol *sym)
253{ 253{
254 struct rb_node **p = &self->rb_node; 254 struct rb_node **p = &symbols->rb_node;
255 struct rb_node *parent = NULL; 255 struct rb_node *parent = NULL;
256 const u64 ip = sym->start; 256 const u64 ip = sym->start;
257 struct symbol *s; 257 struct symbol *s;
@@ -265,17 +265,17 @@ static void symbols__insert(struct rb_root *self, struct symbol *sym)
265 p = &(*p)->rb_right; 265 p = &(*p)->rb_right;
266 } 266 }
267 rb_link_node(&sym->rb_node, parent, p); 267 rb_link_node(&sym->rb_node, parent, p);
268 rb_insert_color(&sym->rb_node, self); 268 rb_insert_color(&sym->rb_node, symbols);
269} 269}
270 270
271static struct symbol *symbols__find(struct rb_root *self, u64 ip) 271static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
272{ 272{
273 struct rb_node *n; 273 struct rb_node *n;
274 274
275 if (self == NULL) 275 if (symbols == NULL)
276 return NULL; 276 return NULL;
277 277
278 n = self->rb_node; 278 n = symbols->rb_node;
279 279
280 while (n) { 280 while (n) {
281 struct symbol *s = rb_entry(n, struct symbol, rb_node); 281 struct symbol *s = rb_entry(n, struct symbol, rb_node);
@@ -296,9 +296,9 @@ struct symbol_name_rb_node {
296 struct symbol sym; 296 struct symbol sym;
297}; 297};
298 298
299static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym) 299static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
300{ 300{
301 struct rb_node **p = &self->rb_node; 301 struct rb_node **p = &symbols->rb_node;
302 struct rb_node *parent = NULL; 302 struct rb_node *parent = NULL;
303 struct symbol_name_rb_node *symn, *s; 303 struct symbol_name_rb_node *symn, *s;
304 304
@@ -313,27 +313,29 @@ static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym)
313 p = &(*p)->rb_right; 313 p = &(*p)->rb_right;
314 } 314 }
315 rb_link_node(&symn->rb_node, parent, p); 315 rb_link_node(&symn->rb_node, parent, p);
316 rb_insert_color(&symn->rb_node, self); 316 rb_insert_color(&symn->rb_node, symbols);
317} 317}
318 318
319static void symbols__sort_by_name(struct rb_root *self, struct rb_root *source) 319static void symbols__sort_by_name(struct rb_root *symbols,
320 struct rb_root *source)
320{ 321{
321 struct rb_node *nd; 322 struct rb_node *nd;
322 323
323 for (nd = rb_first(source); nd; nd = rb_next(nd)) { 324 for (nd = rb_first(source); nd; nd = rb_next(nd)) {
324 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 325 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
325 symbols__insert_by_name(self, pos); 326 symbols__insert_by_name(symbols, pos);
326 } 327 }
327} 328}
328 329
329static struct symbol *symbols__find_by_name(struct rb_root *self, const char *name) 330static struct symbol *symbols__find_by_name(struct rb_root *symbols,
331 const char *name)
330{ 332{
331 struct rb_node *n; 333 struct rb_node *n;
332 334
333 if (self == NULL) 335 if (symbols == NULL)
334 return NULL; 336 return NULL;
335 337
336 n = self->rb_node; 338 n = symbols->rb_node;
337 339
338 while (n) { 340 while (n) {
339 struct symbol_name_rb_node *s; 341 struct symbol_name_rb_node *s;
@@ -353,29 +355,29 @@ static struct symbol *symbols__find_by_name(struct rb_root *self, const char *na
353 return NULL; 355 return NULL;
354} 356}
355 357
356struct symbol *dso__find_symbol(struct dso *self, 358struct symbol *dso__find_symbol(struct dso *dso,
357 enum map_type type, u64 addr) 359 enum map_type type, u64 addr)
358{ 360{
359 return symbols__find(&self->symbols[type], addr); 361 return symbols__find(&dso->symbols[type], addr);
360} 362}
361 363
362struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type, 364struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
363 const char *name) 365 const char *name)
364{ 366{
365 return symbols__find_by_name(&self->symbol_names[type], name); 367 return symbols__find_by_name(&dso->symbol_names[type], name);
366} 368}
367 369
368void dso__sort_by_name(struct dso *self, enum map_type type) 370void dso__sort_by_name(struct dso *dso, enum map_type type)
369{ 371{
370 dso__set_sorted_by_name(self, type); 372 dso__set_sorted_by_name(dso, type);
371 return symbols__sort_by_name(&self->symbol_names[type], 373 return symbols__sort_by_name(&dso->symbol_names[type],
372 &self->symbols[type]); 374 &dso->symbols[type]);
373} 375}
374 376
375int build_id__sprintf(const u8 *self, int len, char *bf) 377int build_id__sprintf(const u8 *build_id, int len, char *bf)
376{ 378{
377 char *bid = bf; 379 char *bid = bf;
378 const u8 *raw = self; 380 const u8 *raw = build_id;
379 int i; 381 int i;
380 382
381 for (i = 0; i < len; ++i) { 383 for (i = 0; i < len; ++i) {
@@ -384,24 +386,25 @@ int build_id__sprintf(const u8 *self, int len, char *bf)
384 bid += 2; 386 bid += 2;
385 } 387 }
386 388
387 return raw - self; 389 return raw - build_id;
388} 390}
389 391
390size_t dso__fprintf_buildid(struct dso *self, FILE *fp) 392size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
391{ 393{
392 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 394 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
393 395
394 build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id); 396 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
395 return fprintf(fp, "%s", sbuild_id); 397 return fprintf(fp, "%s", sbuild_id);
396} 398}
397 399
398size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp) 400size_t dso__fprintf_symbols_by_name(struct dso *dso,
401 enum map_type type, FILE *fp)
399{ 402{
400 size_t ret = 0; 403 size_t ret = 0;
401 struct rb_node *nd; 404 struct rb_node *nd;
402 struct symbol_name_rb_node *pos; 405 struct symbol_name_rb_node *pos;
403 406
404 for (nd = rb_first(&self->symbol_names[type]); nd; nd = rb_next(nd)) { 407 for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
405 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); 408 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
406 fprintf(fp, "%s\n", pos->sym.name); 409 fprintf(fp, "%s\n", pos->sym.name);
407 } 410 }
@@ -409,18 +412,18 @@ size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *
409 return ret; 412 return ret;
410} 413}
411 414
412size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp) 415size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
413{ 416{
414 struct rb_node *nd; 417 struct rb_node *nd;
415 size_t ret = fprintf(fp, "dso: %s (", self->short_name); 418 size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
416 419
417 if (self->short_name != self->long_name) 420 if (dso->short_name != dso->long_name)
418 ret += fprintf(fp, "%s, ", self->long_name); 421 ret += fprintf(fp, "%s, ", dso->long_name);
419 ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type], 422 ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
420 self->loaded ? "" : "NOT "); 423 dso->loaded ? "" : "NOT ");
421 ret += dso__fprintf_buildid(self, fp); 424 ret += dso__fprintf_buildid(dso, fp);
422 ret += fprintf(fp, ")\n"); 425 ret += fprintf(fp, ")\n");
423 for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) { 426 for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
424 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 427 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
425 ret += symbol__fprintf(pos, fp); 428 ret += symbol__fprintf(pos, fp);
426 } 429 }
@@ -543,10 +546,10 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
543 * so that we can in the next step set the symbol ->end address and then 546 * so that we can in the next step set the symbol ->end address and then
544 * call kernel_maps__split_kallsyms. 547 * call kernel_maps__split_kallsyms.
545 */ 548 */
546static int dso__load_all_kallsyms(struct dso *self, const char *filename, 549static int dso__load_all_kallsyms(struct dso *dso, const char *filename,
547 struct map *map) 550 struct map *map)
548{ 551{
549 struct process_kallsyms_args args = { .map = map, .dso = self, }; 552 struct process_kallsyms_args args = { .map = map, .dso = dso, };
550 return kallsyms__parse(filename, &args, map__process_kallsym_symbol); 553 return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
551} 554}
552 555
@@ -555,7 +558,7 @@ static int dso__load_all_kallsyms(struct dso *self, const char *filename,
555 * kernel range is broken in several maps, named [kernel].N, as we don't have 558 * kernel range is broken in several maps, named [kernel].N, as we don't have
556 * the original ELF section names vmlinux have. 559 * the original ELF section names vmlinux have.
557 */ 560 */
558static int dso__split_kallsyms(struct dso *self, struct map *map, 561static int dso__split_kallsyms(struct dso *dso, struct map *map,
559 symbol_filter_t filter) 562 symbol_filter_t filter)
560{ 563{
561 struct map_groups *kmaps = map__kmap(map)->kmaps; 564 struct map_groups *kmaps = map__kmap(map)->kmaps;
@@ -563,7 +566,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
563 struct map *curr_map = map; 566 struct map *curr_map = map;
564 struct symbol *pos; 567 struct symbol *pos;
565 int count = 0, moved = 0; 568 int count = 0, moved = 0;
566 struct rb_root *root = &self->symbols[map->type]; 569 struct rb_root *root = &dso->symbols[map->type];
567 struct rb_node *next = rb_first(root); 570 struct rb_node *next = rb_first(root);
568 int kernel_range = 0; 571 int kernel_range = 0;
569 572
@@ -582,7 +585,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
582 585
583 if (strcmp(curr_map->dso->short_name, module)) { 586 if (strcmp(curr_map->dso->short_name, module)) {
584 if (curr_map != map && 587 if (curr_map != map &&
585 self->kernel == DSO_TYPE_GUEST_KERNEL && 588 dso->kernel == DSO_TYPE_GUEST_KERNEL &&
586 machine__is_default_guest(machine)) { 589 machine__is_default_guest(machine)) {
587 /* 590 /*
588 * We assume all symbols of a module are 591 * We assume all symbols of a module are
@@ -618,14 +621,14 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
618 pos->end = curr_map->map_ip(curr_map, pos->end); 621 pos->end = curr_map->map_ip(curr_map, pos->end);
619 } else if (curr_map != map) { 622 } else if (curr_map != map) {
620 char dso_name[PATH_MAX]; 623 char dso_name[PATH_MAX];
621 struct dso *dso; 624 struct dso *ndso;
622 625
623 if (count == 0) { 626 if (count == 0) {
624 curr_map = map; 627 curr_map = map;
625 goto filter_symbol; 628 goto filter_symbol;
626 } 629 }
627 630
628 if (self->kernel == DSO_TYPE_GUEST_KERNEL) 631 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
629 snprintf(dso_name, sizeof(dso_name), 632 snprintf(dso_name, sizeof(dso_name),
630 "[guest.kernel].%d", 633 "[guest.kernel].%d",
631 kernel_range++); 634 kernel_range++);
@@ -634,15 +637,15 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
634 "[kernel].%d", 637 "[kernel].%d",
635 kernel_range++); 638 kernel_range++);
636 639
637 dso = dso__new(dso_name); 640 ndso = dso__new(dso_name);
638 if (dso == NULL) 641 if (ndso == NULL)
639 return -1; 642 return -1;
640 643
641 dso->kernel = self->kernel; 644 ndso->kernel = dso->kernel;
642 645
643 curr_map = map__new2(pos->start, dso, map->type); 646 curr_map = map__new2(pos->start, ndso, map->type);
644 if (curr_map == NULL) { 647 if (curr_map == NULL) {
645 dso__delete(dso); 648 dso__delete(ndso);
646 return -1; 649 return -1;
647 } 650 }
648 651
@@ -665,7 +668,7 @@ discard_symbol: rb_erase(&pos->rb_node, root);
665 } 668 }
666 669
667 if (curr_map != map && 670 if (curr_map != map &&
668 self->kernel == DSO_TYPE_GUEST_KERNEL && 671 dso->kernel == DSO_TYPE_GUEST_KERNEL &&
669 machine__is_default_guest(kmaps->machine)) { 672 machine__is_default_guest(kmaps->machine)) {
670 dso__set_loaded(curr_map->dso, curr_map->type); 673 dso__set_loaded(curr_map->dso, curr_map->type);
671 } 674 }
@@ -673,21 +676,21 @@ discard_symbol: rb_erase(&pos->rb_node, root);
673 return count + moved; 676 return count + moved;
674} 677}
675 678
676int dso__load_kallsyms(struct dso *self, const char *filename, 679int dso__load_kallsyms(struct dso *dso, const char *filename,
677 struct map *map, symbol_filter_t filter) 680 struct map *map, symbol_filter_t filter)
678{ 681{
679 if (dso__load_all_kallsyms(self, filename, map) < 0) 682 if (dso__load_all_kallsyms(dso, filename, map) < 0)
680 return -1; 683 return -1;
681 684
682 if (self->kernel == DSO_TYPE_GUEST_KERNEL) 685 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
683 self->symtab_type = SYMTAB__GUEST_KALLSYMS; 686 dso->symtab_type = SYMTAB__GUEST_KALLSYMS;
684 else 687 else
685 self->symtab_type = SYMTAB__KALLSYMS; 688 dso->symtab_type = SYMTAB__KALLSYMS;
686 689
687 return dso__split_kallsyms(self, map, filter); 690 return dso__split_kallsyms(dso, map, filter);
688} 691}
689 692
690static int dso__load_perf_map(struct dso *self, struct map *map, 693static int dso__load_perf_map(struct dso *dso, struct map *map,
691 symbol_filter_t filter) 694 symbol_filter_t filter)
692{ 695{
693 char *line = NULL; 696 char *line = NULL;
@@ -695,7 +698,7 @@ static int dso__load_perf_map(struct dso *self, struct map *map,
695 FILE *file; 698 FILE *file;
696 int nr_syms = 0; 699 int nr_syms = 0;
697 700
698 file = fopen(self->long_name, "r"); 701 file = fopen(dso->long_name, "r");
699 if (file == NULL) 702 if (file == NULL)
700 goto out_failure; 703 goto out_failure;
701 704
@@ -733,7 +736,7 @@ static int dso__load_perf_map(struct dso *self, struct map *map,
733 if (filter && filter(map, sym)) 736 if (filter && filter(map, sym))
734 symbol__delete(sym); 737 symbol__delete(sym);
735 else { 738 else {
736 symbols__insert(&self->symbols[map->type], sym); 739 symbols__insert(&dso->symbols[map->type], sym);
737 nr_syms++; 740 nr_syms++;
738 } 741 }
739 } 742 }
@@ -752,7 +755,7 @@ out_failure:
752/** 755/**
753 * elf_symtab__for_each_symbol - iterate thru all the symbols 756 * elf_symtab__for_each_symbol - iterate thru all the symbols
754 * 757 *
755 * @self: struct elf_symtab instance to iterate 758 * @syms: struct elf_symtab instance to iterate
756 * @idx: uint32_t idx 759 * @idx: uint32_t idx
757 * @sym: GElf_Sym iterator 760 * @sym: GElf_Sym iterator
758 */ 761 */
@@ -852,7 +855,7 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
852 * And always look at the original dso, not at debuginfo packages, that 855 * And always look at the original dso, not at debuginfo packages, that
853 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). 856 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
854 */ 857 */
855static int dso__synthesize_plt_symbols(struct dso *self, struct map *map, 858static int dso__synthesize_plt_symbols(struct dso *dso, struct map *map,
856 symbol_filter_t filter) 859 symbol_filter_t filter)
857{ 860{
858 uint32_t nr_rel_entries, idx; 861 uint32_t nr_rel_entries, idx;
@@ -871,7 +874,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
871 char name[PATH_MAX]; 874 char name[PATH_MAX];
872 875
873 snprintf(name, sizeof(name), "%s%s", 876 snprintf(name, sizeof(name), "%s%s",
874 symbol_conf.symfs, self->long_name); 877 symbol_conf.symfs, dso->long_name);
875 fd = open(name, O_RDONLY); 878 fd = open(name, O_RDONLY);
876 if (fd < 0) 879 if (fd < 0)
877 goto out; 880 goto out;
@@ -947,7 +950,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
947 if (filter && filter(map, f)) 950 if (filter && filter(map, f))
948 symbol__delete(f); 951 symbol__delete(f);
949 else { 952 else {
950 symbols__insert(&self->symbols[map->type], f); 953 symbols__insert(&dso->symbols[map->type], f);
951 ++nr; 954 ++nr;
952 } 955 }
953 } 956 }
@@ -969,7 +972,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
969 if (filter && filter(map, f)) 972 if (filter && filter(map, f))
970 symbol__delete(f); 973 symbol__delete(f);
971 else { 974 else {
972 symbols__insert(&self->symbols[map->type], f); 975 symbols__insert(&dso->symbols[map->type], f);
973 ++nr; 976 ++nr;
974 } 977 }
975 } 978 }
@@ -985,29 +988,30 @@ out_close:
985 return nr; 988 return nr;
986out: 989out:
987 pr_debug("%s: problems reading %s PLT info.\n", 990 pr_debug("%s: problems reading %s PLT info.\n",
988 __func__, self->long_name); 991 __func__, dso->long_name);
989 return 0; 992 return 0;
990} 993}
991 994
992static bool elf_sym__is_a(GElf_Sym *self, enum map_type type) 995static bool elf_sym__is_a(GElf_Sym *sym, enum map_type type)
993{ 996{
994 switch (type) { 997 switch (type) {
995 case MAP__FUNCTION: 998 case MAP__FUNCTION:
996 return elf_sym__is_function(self); 999 return elf_sym__is_function(sym);
997 case MAP__VARIABLE: 1000 case MAP__VARIABLE:
998 return elf_sym__is_object(self); 1001 return elf_sym__is_object(sym);
999 default: 1002 default:
1000 return false; 1003 return false;
1001 } 1004 }
1002} 1005}
1003 1006
1004static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type) 1007static bool elf_sec__is_a(GElf_Shdr *shdr, Elf_Data *secstrs,
1008 enum map_type type)
1005{ 1009{
1006 switch (type) { 1010 switch (type) {
1007 case MAP__FUNCTION: 1011 case MAP__FUNCTION:
1008 return elf_sec__is_text(self, secstrs); 1012 return elf_sec__is_text(shdr, secstrs);
1009 case MAP__VARIABLE: 1013 case MAP__VARIABLE:
1010 return elf_sec__is_data(self, secstrs); 1014 return elf_sec__is_data(shdr, secstrs);
1011 default: 1015 default:
1012 return false; 1016 return false;
1013 } 1017 }
@@ -1032,13 +1036,13 @@ static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
1032 return -1; 1036 return -1;
1033} 1037}
1034 1038
1035static int dso__load_sym(struct dso *self, struct map *map, const char *name, 1039static int dso__load_sym(struct dso *dso, struct map *map, const char *name,
1036 int fd, symbol_filter_t filter, int kmodule, 1040 int fd, symbol_filter_t filter, int kmodule,
1037 int want_symtab) 1041 int want_symtab)
1038{ 1042{
1039 struct kmap *kmap = self->kernel ? map__kmap(map) : NULL; 1043 struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL;
1040 struct map *curr_map = map; 1044 struct map *curr_map = map;
1041 struct dso *curr_dso = self; 1045 struct dso *curr_dso = dso;
1042 Elf_Data *symstrs, *secstrs; 1046 Elf_Data *symstrs, *secstrs;
1043 uint32_t nr_syms; 1047 uint32_t nr_syms;
1044 int err = -1; 1048 int err = -1;
@@ -1064,14 +1068,14 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1064 } 1068 }
1065 1069
1066 /* Always reject images with a mismatched build-id: */ 1070 /* Always reject images with a mismatched build-id: */
1067 if (self->has_build_id) { 1071 if (dso->has_build_id) {
1068 u8 build_id[BUILD_ID_SIZE]; 1072 u8 build_id[BUILD_ID_SIZE];
1069 1073
1070 if (elf_read_build_id(elf, build_id, 1074 if (elf_read_build_id(elf, build_id,
1071 BUILD_ID_SIZE) != BUILD_ID_SIZE) 1075 BUILD_ID_SIZE) != BUILD_ID_SIZE)
1072 goto out_elf_end; 1076 goto out_elf_end;
1073 1077
1074 if (!dso__build_id_equal(self, build_id)) 1078 if (!dso__build_id_equal(dso, build_id))
1075 goto out_elf_end; 1079 goto out_elf_end;
1076 } 1080 }
1077 1081
@@ -1112,13 +1116,14 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1112 nr_syms = shdr.sh_size / shdr.sh_entsize; 1116 nr_syms = shdr.sh_size / shdr.sh_entsize;
1113 1117
1114 memset(&sym, 0, sizeof(sym)); 1118 memset(&sym, 0, sizeof(sym));
1115 if (self->kernel == DSO_TYPE_USER) { 1119 if (dso->kernel == DSO_TYPE_USER) {
1116 self->adjust_symbols = (ehdr.e_type == ET_EXEC || 1120 dso->adjust_symbols = (ehdr.e_type == ET_EXEC ||
1117 elf_section_by_name(elf, &ehdr, &shdr, 1121 elf_section_by_name(elf, &ehdr, &shdr,
1118 ".gnu.prelink_undo", 1122 ".gnu.prelink_undo",
1119 NULL) != NULL); 1123 NULL) != NULL);
1120 } else self->adjust_symbols = 0; 1124 } else {
1121 1125 dso->adjust_symbols = 0;
1126 }
1122 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { 1127 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
1123 struct symbol *f; 1128 struct symbol *f;
1124 const char *elf_name = elf_sym__name(&sym, symstrs); 1129 const char *elf_name = elf_sym__name(&sym, symstrs);
@@ -1168,22 +1173,22 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1168 (sym.st_value & 1)) 1173 (sym.st_value & 1))
1169 --sym.st_value; 1174 --sym.st_value;
1170 1175
1171 if (self->kernel != DSO_TYPE_USER || kmodule) { 1176 if (dso->kernel != DSO_TYPE_USER || kmodule) {
1172 char dso_name[PATH_MAX]; 1177 char dso_name[PATH_MAX];
1173 1178
1174 if (strcmp(section_name, 1179 if (strcmp(section_name,
1175 (curr_dso->short_name + 1180 (curr_dso->short_name +
1176 self->short_name_len)) == 0) 1181 dso->short_name_len)) == 0)
1177 goto new_symbol; 1182 goto new_symbol;
1178 1183
1179 if (strcmp(section_name, ".text") == 0) { 1184 if (strcmp(section_name, ".text") == 0) {
1180 curr_map = map; 1185 curr_map = map;
1181 curr_dso = self; 1186 curr_dso = dso;
1182 goto new_symbol; 1187 goto new_symbol;
1183 } 1188 }
1184 1189
1185 snprintf(dso_name, sizeof(dso_name), 1190 snprintf(dso_name, sizeof(dso_name),
1186 "%s%s", self->short_name, section_name); 1191 "%s%s", dso->short_name, section_name);
1187 1192
1188 curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name); 1193 curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
1189 if (curr_map == NULL) { 1194 if (curr_map == NULL) {
@@ -1195,9 +1200,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1195 curr_dso = dso__new(dso_name); 1200 curr_dso = dso__new(dso_name);
1196 if (curr_dso == NULL) 1201 if (curr_dso == NULL)
1197 goto out_elf_end; 1202 goto out_elf_end;
1198 curr_dso->kernel = self->kernel; 1203 curr_dso->kernel = dso->kernel;
1199 curr_dso->long_name = self->long_name; 1204 curr_dso->long_name = dso->long_name;
1200 curr_dso->long_name_len = self->long_name_len; 1205 curr_dso->long_name_len = dso->long_name_len;
1201 curr_map = map__new2(start, curr_dso, 1206 curr_map = map__new2(start, curr_dso,
1202 map->type); 1207 map->type);
1203 if (curr_map == NULL) { 1208 if (curr_map == NULL) {
@@ -1206,9 +1211,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1206 } 1211 }
1207 curr_map->map_ip = identity__map_ip; 1212 curr_map->map_ip = identity__map_ip;
1208 curr_map->unmap_ip = identity__map_ip; 1213 curr_map->unmap_ip = identity__map_ip;
1209 curr_dso->symtab_type = self->symtab_type; 1214 curr_dso->symtab_type = dso->symtab_type;
1210 map_groups__insert(kmap->kmaps, curr_map); 1215 map_groups__insert(kmap->kmaps, curr_map);
1211 dsos__add(&self->node, curr_dso); 1216 dsos__add(&dso->node, curr_dso);
1212 dso__set_loaded(curr_dso, map->type); 1217 dso__set_loaded(curr_dso, map->type);
1213 } else 1218 } else
1214 curr_dso = curr_map->dso; 1219 curr_dso = curr_map->dso;
@@ -1250,7 +1255,7 @@ new_symbol:
1250 * For misannotated, zeroed, ASM function sizes. 1255 * For misannotated, zeroed, ASM function sizes.
1251 */ 1256 */
1252 if (nr > 0) { 1257 if (nr > 0) {
1253 symbols__fixup_end(&self->symbols[map->type]); 1258 symbols__fixup_end(&dso->symbols[map->type]);
1254 if (kmap) { 1259 if (kmap) {
1255 /* 1260 /*
1256 * We need to fixup this here too because we create new 1261 * We need to fixup this here too because we create new
@@ -1266,9 +1271,9 @@ out_close:
1266 return err; 1271 return err;
1267} 1272}
1268 1273
1269static bool dso__build_id_equal(const struct dso *self, u8 *build_id) 1274static bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
1270{ 1275{
1271 return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0; 1276 return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
1272} 1277}
1273 1278
1274bool __dsos__read_build_ids(struct list_head *head, bool with_hits) 1279bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
@@ -1429,7 +1434,7 @@ out:
1429 return err; 1434 return err;
1430} 1435}
1431 1436
1432char dso__symtab_origin(const struct dso *self) 1437char dso__symtab_origin(const struct dso *dso)
1433{ 1438{
1434 static const char origin[] = { 1439 static const char origin[] = {
1435 [SYMTAB__KALLSYMS] = 'k', 1440 [SYMTAB__KALLSYMS] = 'k',
@@ -1444,12 +1449,12 @@ char dso__symtab_origin(const struct dso *self)
1444 [SYMTAB__GUEST_KMODULE] = 'G', 1449 [SYMTAB__GUEST_KMODULE] = 'G',
1445 }; 1450 };
1446 1451
1447 if (self == NULL || self->symtab_type == SYMTAB__NOT_FOUND) 1452 if (dso == NULL || dso->symtab_type == SYMTAB__NOT_FOUND)
1448 return '!'; 1453 return '!';
1449 return origin[self->symtab_type]; 1454 return origin[dso->symtab_type];
1450} 1455}
1451 1456
1452int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) 1457int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1453{ 1458{
1454 int size = PATH_MAX; 1459 int size = PATH_MAX;
1455 char *name; 1460 char *name;
@@ -1459,12 +1464,12 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1459 const char *root_dir; 1464 const char *root_dir;
1460 int want_symtab; 1465 int want_symtab;
1461 1466
1462 dso__set_loaded(self, map->type); 1467 dso__set_loaded(dso, map->type);
1463 1468
1464 if (self->kernel == DSO_TYPE_KERNEL) 1469 if (dso->kernel == DSO_TYPE_KERNEL)
1465 return dso__load_kernel_sym(self, map, filter); 1470 return dso__load_kernel_sym(dso, map, filter);
1466 else if (self->kernel == DSO_TYPE_GUEST_KERNEL) 1471 else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1467 return dso__load_guest_kernel_sym(self, map, filter); 1472 return dso__load_guest_kernel_sym(dso, map, filter);
1468 1473
1469 if (map->groups && map->groups->machine) 1474 if (map->groups && map->groups->machine)
1470 machine = map->groups->machine; 1475 machine = map->groups->machine;
@@ -1475,11 +1480,11 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1475 if (!name) 1480 if (!name)
1476 return -1; 1481 return -1;
1477 1482
1478 self->adjust_symbols = 0; 1483 dso->adjust_symbols = 0;
1479 1484
1480 if (strncmp(self->name, "/tmp/perf-", 10) == 0) { 1485 if (strncmp(dso->name, "/tmp/perf-", 10) == 0) {
1481 ret = dso__load_perf_map(self, map, filter); 1486 ret = dso__load_perf_map(dso, map, filter);
1482 self->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT : 1487 dso->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT :
1483 SYMTAB__NOT_FOUND; 1488 SYMTAB__NOT_FOUND;
1484 return ret; 1489 return ret;
1485 } 1490 }
@@ -1490,33 +1495,33 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1490 */ 1495 */
1491 want_symtab = 1; 1496 want_symtab = 1;
1492restart: 1497restart:
1493 for (self->symtab_type = SYMTAB__BUILD_ID_CACHE; 1498 for (dso->symtab_type = SYMTAB__BUILD_ID_CACHE;
1494 self->symtab_type != SYMTAB__NOT_FOUND; 1499 dso->symtab_type != SYMTAB__NOT_FOUND;
1495 self->symtab_type++) { 1500 dso->symtab_type++) {
1496 switch (self->symtab_type) { 1501 switch (dso->symtab_type) {
1497 case SYMTAB__BUILD_ID_CACHE: 1502 case SYMTAB__BUILD_ID_CACHE:
1498 /* skip the locally configured cache if a symfs is given */ 1503 /* skip the locally configured cache if a symfs is given */
1499 if (symbol_conf.symfs[0] || 1504 if (symbol_conf.symfs[0] ||
1500 (dso__build_id_filename(self, name, size) == NULL)) { 1505 (dso__build_id_filename(dso, name, size) == NULL)) {
1501 continue; 1506 continue;
1502 } 1507 }
1503 break; 1508 break;
1504 case SYMTAB__FEDORA_DEBUGINFO: 1509 case SYMTAB__FEDORA_DEBUGINFO:
1505 snprintf(name, size, "%s/usr/lib/debug%s.debug", 1510 snprintf(name, size, "%s/usr/lib/debug%s.debug",
1506 symbol_conf.symfs, self->long_name); 1511 symbol_conf.symfs, dso->long_name);
1507 break; 1512 break;
1508 case SYMTAB__UBUNTU_DEBUGINFO: 1513 case SYMTAB__UBUNTU_DEBUGINFO:
1509 snprintf(name, size, "%s/usr/lib/debug%s", 1514 snprintf(name, size, "%s/usr/lib/debug%s",
1510 symbol_conf.symfs, self->long_name); 1515 symbol_conf.symfs, dso->long_name);
1511 break; 1516 break;
1512 case SYMTAB__BUILDID_DEBUGINFO: { 1517 case SYMTAB__BUILDID_DEBUGINFO: {
1513 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 1518 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1514 1519
1515 if (!self->has_build_id) 1520 if (!dso->has_build_id)
1516 continue; 1521 continue;
1517 1522
1518 build_id__sprintf(self->build_id, 1523 build_id__sprintf(dso->build_id,
1519 sizeof(self->build_id), 1524 sizeof(dso->build_id),
1520 build_id_hex); 1525 build_id_hex);
1521 snprintf(name, size, 1526 snprintf(name, size,
1522 "%s/usr/lib/debug/.build-id/%.2s/%s.debug", 1527 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
@@ -1525,7 +1530,7 @@ restart:
1525 break; 1530 break;
1526 case SYMTAB__SYSTEM_PATH_DSO: 1531 case SYMTAB__SYSTEM_PATH_DSO:
1527 snprintf(name, size, "%s%s", 1532 snprintf(name, size, "%s%s",
1528 symbol_conf.symfs, self->long_name); 1533 symbol_conf.symfs, dso->long_name);
1529 break; 1534 break;
1530 case SYMTAB__GUEST_KMODULE: 1535 case SYMTAB__GUEST_KMODULE:
1531 if (map->groups && machine) 1536 if (map->groups && machine)
@@ -1533,12 +1538,12 @@ restart:
1533 else 1538 else
1534 root_dir = ""; 1539 root_dir = "";
1535 snprintf(name, size, "%s%s%s", symbol_conf.symfs, 1540 snprintf(name, size, "%s%s%s", symbol_conf.symfs,
1536 root_dir, self->long_name); 1541 root_dir, dso->long_name);
1537 break; 1542 break;
1538 1543
1539 case SYMTAB__SYSTEM_PATH_KMODULE: 1544 case SYMTAB__SYSTEM_PATH_KMODULE:
1540 snprintf(name, size, "%s%s", symbol_conf.symfs, 1545 snprintf(name, size, "%s%s", symbol_conf.symfs,
1541 self->long_name); 1546 dso->long_name);
1542 break; 1547 break;
1543 default:; 1548 default:;
1544 } 1549 }
@@ -1548,7 +1553,7 @@ restart:
1548 if (fd < 0) 1553 if (fd < 0)
1549 continue; 1554 continue;
1550 1555
1551 ret = dso__load_sym(self, map, name, fd, filter, 0, 1556 ret = dso__load_sym(dso, map, name, fd, filter, 0,
1552 want_symtab); 1557 want_symtab);
1553 close(fd); 1558 close(fd);
1554 1559
@@ -1560,7 +1565,8 @@ restart:
1560 continue; 1565 continue;
1561 1566
1562 if (ret > 0) { 1567 if (ret > 0) {
1563 int nr_plt = dso__synthesize_plt_symbols(self, map, filter); 1568 int nr_plt = dso__synthesize_plt_symbols(dso, map,
1569 filter);
1564 if (nr_plt > 0) 1570 if (nr_plt > 0)
1565 ret += nr_plt; 1571 ret += nr_plt;
1566 break; 1572 break;
@@ -1577,17 +1583,17 @@ restart:
1577 } 1583 }
1578 1584
1579 free(name); 1585 free(name);
1580 if (ret < 0 && strstr(self->name, " (deleted)") != NULL) 1586 if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
1581 return 0; 1587 return 0;
1582 return ret; 1588 return ret;
1583} 1589}
1584 1590
1585struct map *map_groups__find_by_name(struct map_groups *self, 1591struct map *map_groups__find_by_name(struct map_groups *mg,
1586 enum map_type type, const char *name) 1592 enum map_type type, const char *name)
1587{ 1593{
1588 struct rb_node *nd; 1594 struct rb_node *nd;
1589 1595
1590 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) { 1596 for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
1591 struct map *map = rb_entry(nd, struct map, rb_node); 1597 struct map *map = rb_entry(nd, struct map, rb_node);
1592 1598
1593 if (map->dso && strcmp(map->dso->short_name, name) == 0) 1599 if (map->dso && strcmp(map->dso->short_name, name) == 0)
@@ -1597,28 +1603,28 @@ struct map *map_groups__find_by_name(struct map_groups *self,
1597 return NULL; 1603 return NULL;
1598} 1604}
1599 1605
1600static int dso__kernel_module_get_build_id(struct dso *self, 1606static int dso__kernel_module_get_build_id(struct dso *dso,
1601 const char *root_dir) 1607 const char *root_dir)
1602{ 1608{
1603 char filename[PATH_MAX]; 1609 char filename[PATH_MAX];
1604 /* 1610 /*
1605 * kernel module short names are of the form "[module]" and 1611 * kernel module short names are of the form "[module]" and
1606 * we need just "module" here. 1612 * we need just "module" here.
1607 */ 1613 */
1608 const char *name = self->short_name + 1; 1614 const char *name = dso->short_name + 1;
1609 1615
1610 snprintf(filename, sizeof(filename), 1616 snprintf(filename, sizeof(filename),
1611 "%s/sys/module/%.*s/notes/.note.gnu.build-id", 1617 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1612 root_dir, (int)strlen(name) - 1, name); 1618 root_dir, (int)strlen(name) - 1, name);
1613 1619
1614 if (sysfs__read_build_id(filename, self->build_id, 1620 if (sysfs__read_build_id(filename, dso->build_id,
1615 sizeof(self->build_id)) == 0) 1621 sizeof(dso->build_id)) == 0)
1616 self->has_build_id = true; 1622 dso->has_build_id = true;
1617 1623
1618 return 0; 1624 return 0;
1619} 1625}
1620 1626
1621static int map_groups__set_modules_path_dir(struct map_groups *self, 1627static int map_groups__set_modules_path_dir(struct map_groups *mg,
1622 const char *dir_name) 1628 const char *dir_name)
1623{ 1629{
1624 struct dirent *dent; 1630 struct dirent *dent;
@@ -1646,7 +1652,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *self,
1646 1652
1647 snprintf(path, sizeof(path), "%s/%s", 1653 snprintf(path, sizeof(path), "%s/%s",
1648 dir_name, dent->d_name); 1654 dir_name, dent->d_name);
1649 ret = map_groups__set_modules_path_dir(self, path); 1655 ret = map_groups__set_modules_path_dir(mg, path);
1650 if (ret < 0) 1656 if (ret < 0)
1651 goto out; 1657 goto out;
1652 } else { 1658 } else {
@@ -1661,7 +1667,8 @@ static int map_groups__set_modules_path_dir(struct map_groups *self,
1661 (int)(dot - dent->d_name), dent->d_name); 1667 (int)(dot - dent->d_name), dent->d_name);
1662 1668
1663 strxfrchar(dso_name, '-', '_'); 1669 strxfrchar(dso_name, '-', '_');
1664 map = map_groups__find_by_name(self, MAP__FUNCTION, dso_name); 1670 map = map_groups__find_by_name(mg, MAP__FUNCTION,
1671 dso_name);
1665 if (map == NULL) 1672 if (map == NULL)
1666 continue; 1673 continue;
1667 1674
@@ -1711,20 +1718,20 @@ static char *get_kernel_version(const char *root_dir)
1711 return strdup(name); 1718 return strdup(name);
1712} 1719}
1713 1720
1714static int machine__set_modules_path(struct machine *self) 1721static int machine__set_modules_path(struct machine *machine)
1715{ 1722{
1716 char *version; 1723 char *version;
1717 char modules_path[PATH_MAX]; 1724 char modules_path[PATH_MAX];
1718 1725
1719 version = get_kernel_version(self->root_dir); 1726 version = get_kernel_version(machine->root_dir);
1720 if (!version) 1727 if (!version)
1721 return -1; 1728 return -1;
1722 1729
1723 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", 1730 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
1724 self->root_dir, version); 1731 machine->root_dir, version);
1725 free(version); 1732 free(version);
1726 1733
1727 return map_groups__set_modules_path_dir(&self->kmaps, modules_path); 1734 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path);
1728} 1735}
1729 1736
1730/* 1737/*
@@ -1734,23 +1741,23 @@ static int machine__set_modules_path(struct machine *self)
1734 */ 1741 */
1735static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) 1742static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1736{ 1743{
1737 struct map *self = calloc(1, (sizeof(*self) + 1744 struct map *map = calloc(1, (sizeof(*map) +
1738 (dso->kernel ? sizeof(struct kmap) : 0))); 1745 (dso->kernel ? sizeof(struct kmap) : 0)));
1739 if (self != NULL) { 1746 if (map != NULL) {
1740 /* 1747 /*
1741 * ->end will be filled after we load all the symbols 1748 * ->end will be filled after we load all the symbols
1742 */ 1749 */
1743 map__init(self, type, start, 0, 0, dso); 1750 map__init(map, type, start, 0, 0, dso);
1744 } 1751 }
1745 1752
1746 return self; 1753 return map;
1747} 1754}
1748 1755
1749struct map *machine__new_module(struct machine *self, u64 start, 1756struct map *machine__new_module(struct machine *machine, u64 start,
1750 const char *filename) 1757 const char *filename)
1751{ 1758{
1752 struct map *map; 1759 struct map *map;
1753 struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename); 1760 struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename);
1754 1761
1755 if (dso == NULL) 1762 if (dso == NULL)
1756 return NULL; 1763 return NULL;
@@ -1759,15 +1766,15 @@ struct map *machine__new_module(struct machine *self, u64 start,
1759 if (map == NULL) 1766 if (map == NULL)
1760 return NULL; 1767 return NULL;
1761 1768
1762 if (machine__is_host(self)) 1769 if (machine__is_host(machine))
1763 dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE; 1770 dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE;
1764 else 1771 else
1765 dso->symtab_type = SYMTAB__GUEST_KMODULE; 1772 dso->symtab_type = SYMTAB__GUEST_KMODULE;
1766 map_groups__insert(&self->kmaps, map); 1773 map_groups__insert(&machine->kmaps, map);
1767 return map; 1774 return map;
1768} 1775}
1769 1776
1770static int machine__create_modules(struct machine *self) 1777static int machine__create_modules(struct machine *machine)
1771{ 1778{
1772 char *line = NULL; 1779 char *line = NULL;
1773 size_t n; 1780 size_t n;
@@ -1776,10 +1783,10 @@ static int machine__create_modules(struct machine *self)
1776 const char *modules; 1783 const char *modules;
1777 char path[PATH_MAX]; 1784 char path[PATH_MAX];
1778 1785
1779 if (machine__is_default_guest(self)) 1786 if (machine__is_default_guest(machine))
1780 modules = symbol_conf.default_guest_modules; 1787 modules = symbol_conf.default_guest_modules;
1781 else { 1788 else {
1782 sprintf(path, "%s/proc/modules", self->root_dir); 1789 sprintf(path, "%s/proc/modules", machine->root_dir);
1783 modules = path; 1790 modules = path;
1784 } 1791 }
1785 1792
@@ -1815,16 +1822,16 @@ static int machine__create_modules(struct machine *self)
1815 *sep = '\0'; 1822 *sep = '\0';
1816 1823
1817 snprintf(name, sizeof(name), "[%s]", line); 1824 snprintf(name, sizeof(name), "[%s]", line);
1818 map = machine__new_module(self, start, name); 1825 map = machine__new_module(machine, start, name);
1819 if (map == NULL) 1826 if (map == NULL)
1820 goto out_delete_line; 1827 goto out_delete_line;
1821 dso__kernel_module_get_build_id(map->dso, self->root_dir); 1828 dso__kernel_module_get_build_id(map->dso, machine->root_dir);
1822 } 1829 }
1823 1830
1824 free(line); 1831 free(line);
1825 fclose(file); 1832 fclose(file);
1826 1833
1827 return machine__set_modules_path(self); 1834 return machine__set_modules_path(machine);
1828 1835
1829out_delete_line: 1836out_delete_line:
1830 free(line); 1837 free(line);
@@ -1832,7 +1839,7 @@ out_failure:
1832 return -1; 1839 return -1;
1833} 1840}
1834 1841
1835int dso__load_vmlinux(struct dso *self, struct map *map, 1842int dso__load_vmlinux(struct dso *dso, struct map *map,
1836 const char *vmlinux, symbol_filter_t filter) 1843 const char *vmlinux, symbol_filter_t filter)
1837{ 1844{
1838 int err = -1, fd; 1845 int err = -1, fd;
@@ -1844,9 +1851,9 @@ int dso__load_vmlinux(struct dso *self, struct map *map,
1844 if (fd < 0) 1851 if (fd < 0)
1845 return -1; 1852 return -1;
1846 1853
1847 dso__set_long_name(self, (char *)vmlinux); 1854 dso__set_long_name(dso, (char *)vmlinux);
1848 dso__set_loaded(self, map->type); 1855 dso__set_loaded(dso, map->type);
1849 err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); 1856 err = dso__load_sym(dso, map, symfs_vmlinux, fd, filter, 0, 0);
1850 close(fd); 1857 close(fd);
1851 1858
1852 if (err > 0) 1859 if (err > 0)
@@ -1855,7 +1862,7 @@ int dso__load_vmlinux(struct dso *self, struct map *map,
1855 return err; 1862 return err;
1856} 1863}
1857 1864
1858int dso__load_vmlinux_path(struct dso *self, struct map *map, 1865int dso__load_vmlinux_path(struct dso *dso, struct map *map,
1859 symbol_filter_t filter) 1866 symbol_filter_t filter)
1860{ 1867{
1861 int i, err = 0; 1868 int i, err = 0;
@@ -1864,20 +1871,20 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map,
1864 pr_debug("Looking at the vmlinux_path (%d entries long)\n", 1871 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1865 vmlinux_path__nr_entries + 1); 1872 vmlinux_path__nr_entries + 1);
1866 1873
1867 filename = dso__build_id_filename(self, NULL, 0); 1874 filename = dso__build_id_filename(dso, NULL, 0);
1868 if (filename != NULL) { 1875 if (filename != NULL) {
1869 err = dso__load_vmlinux(self, map, filename, filter); 1876 err = dso__load_vmlinux(dso, map, filename, filter);
1870 if (err > 0) { 1877 if (err > 0) {
1871 dso__set_long_name(self, filename); 1878 dso__set_long_name(dso, filename);
1872 goto out; 1879 goto out;
1873 } 1880 }
1874 free(filename); 1881 free(filename);
1875 } 1882 }
1876 1883
1877 for (i = 0; i < vmlinux_path__nr_entries; ++i) { 1884 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1878 err = dso__load_vmlinux(self, map, vmlinux_path[i], filter); 1885 err = dso__load_vmlinux(dso, map, vmlinux_path[i], filter);
1879 if (err > 0) { 1886 if (err > 0) {
1880 dso__set_long_name(self, strdup(vmlinux_path[i])); 1887 dso__set_long_name(dso, strdup(vmlinux_path[i]));
1881 break; 1888 break;
1882 } 1889 }
1883 } 1890 }
@@ -1885,7 +1892,7 @@ out:
1885 return err; 1892 return err;
1886} 1893}
1887 1894
1888static int dso__load_kernel_sym(struct dso *self, struct map *map, 1895static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1889 symbol_filter_t filter) 1896 symbol_filter_t filter)
1890{ 1897{
1891 int err; 1898 int err;
@@ -1912,10 +1919,10 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1912 } 1919 }
1913 1920
1914 if (symbol_conf.vmlinux_name != NULL) { 1921 if (symbol_conf.vmlinux_name != NULL) {
1915 err = dso__load_vmlinux(self, map, 1922 err = dso__load_vmlinux(dso, map,
1916 symbol_conf.vmlinux_name, filter); 1923 symbol_conf.vmlinux_name, filter);
1917 if (err > 0) { 1924 if (err > 0) {
1918 dso__set_long_name(self, 1925 dso__set_long_name(dso,
1919 strdup(symbol_conf.vmlinux_name)); 1926 strdup(symbol_conf.vmlinux_name));
1920 goto out_fixup; 1927 goto out_fixup;
1921 } 1928 }
@@ -1923,7 +1930,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1923 } 1930 }
1924 1931
1925 if (vmlinux_path != NULL) { 1932 if (vmlinux_path != NULL) {
1926 err = dso__load_vmlinux_path(self, map, filter); 1933 err = dso__load_vmlinux_path(dso, map, filter);
1927 if (err > 0) 1934 if (err > 0)
1928 goto out_fixup; 1935 goto out_fixup;
1929 } 1936 }
@@ -1937,13 +1944,13 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1937 * we have a build-id, so check if it is the same as the running kernel, 1944 * we have a build-id, so check if it is the same as the running kernel,
1938 * using it if it is. 1945 * using it if it is.
1939 */ 1946 */
1940 if (self->has_build_id) { 1947 if (dso->has_build_id) {
1941 u8 kallsyms_build_id[BUILD_ID_SIZE]; 1948 u8 kallsyms_build_id[BUILD_ID_SIZE];
1942 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 1949 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1943 1950
1944 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id, 1951 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1945 sizeof(kallsyms_build_id)) == 0) { 1952 sizeof(kallsyms_build_id)) == 0) {
1946 if (dso__build_id_equal(self, kallsyms_build_id)) { 1953 if (dso__build_id_equal(dso, kallsyms_build_id)) {
1947 kallsyms_filename = "/proc/kallsyms"; 1954 kallsyms_filename = "/proc/kallsyms";
1948 goto do_kallsyms; 1955 goto do_kallsyms;
1949 } 1956 }
@@ -1952,7 +1959,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1952 * Now look if we have it on the build-id cache in 1959 * Now look if we have it on the build-id cache in
1953 * $HOME/.debug/[kernel.kallsyms]. 1960 * $HOME/.debug/[kernel.kallsyms].
1954 */ 1961 */
1955 build_id__sprintf(self->build_id, sizeof(self->build_id), 1962 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
1956 sbuild_id); 1963 sbuild_id);
1957 1964
1958 if (asprintf(&kallsyms_allocated_filename, 1965 if (asprintf(&kallsyms_allocated_filename,
@@ -1979,7 +1986,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1979 } 1986 }
1980 1987
1981do_kallsyms: 1988do_kallsyms:
1982 err = dso__load_kallsyms(self, kallsyms_filename, map, filter); 1989 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
1983 if (err > 0) 1990 if (err > 0)
1984 pr_debug("Using %s for symbols\n", kallsyms_filename); 1991 pr_debug("Using %s for symbols\n", kallsyms_filename);
1985 free(kallsyms_allocated_filename); 1992 free(kallsyms_allocated_filename);
@@ -1987,7 +1994,7 @@ do_kallsyms:
1987 if (err > 0) { 1994 if (err > 0) {
1988out_fixup: 1995out_fixup:
1989 if (kallsyms_filename != NULL) 1996 if (kallsyms_filename != NULL)
1990 dso__set_long_name(self, strdup("[kernel.kallsyms]")); 1997 dso__set_long_name(dso, strdup("[kernel.kallsyms]"));
1991 map__fixup_start(map); 1998 map__fixup_start(map);
1992 map__fixup_end(map); 1999 map__fixup_end(map);
1993 } 2000 }
@@ -1995,8 +2002,8 @@ out_fixup:
1995 return err; 2002 return err;
1996} 2003}
1997 2004
1998static int dso__load_guest_kernel_sym(struct dso *self, struct map *map, 2005static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
1999 symbol_filter_t filter) 2006 symbol_filter_t filter)
2000{ 2007{
2001 int err; 2008 int err;
2002 const char *kallsyms_filename = NULL; 2009 const char *kallsyms_filename = NULL;
@@ -2016,7 +2023,7 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
2016 * Or use file guest_kallsyms inputted by user on commandline 2023 * Or use file guest_kallsyms inputted by user on commandline
2017 */ 2024 */
2018 if (symbol_conf.default_guest_vmlinux_name != NULL) { 2025 if (symbol_conf.default_guest_vmlinux_name != NULL) {
2019 err = dso__load_vmlinux(self, map, 2026 err = dso__load_vmlinux(dso, map,
2020 symbol_conf.default_guest_vmlinux_name, filter); 2027 symbol_conf.default_guest_vmlinux_name, filter);
2021 goto out_try_fixup; 2028 goto out_try_fixup;
2022 } 2029 }
@@ -2029,7 +2036,7 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
2029 kallsyms_filename = path; 2036 kallsyms_filename = path;
2030 } 2037 }
2031 2038
2032 err = dso__load_kallsyms(self, kallsyms_filename, map, filter); 2039 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
2033 if (err > 0) 2040 if (err > 0)
2034 pr_debug("Using %s for symbols\n", kallsyms_filename); 2041 pr_debug("Using %s for symbols\n", kallsyms_filename);
2035 2042
@@ -2037,7 +2044,7 @@ out_try_fixup:
2037 if (err > 0) { 2044 if (err > 0) {
2038 if (kallsyms_filename != NULL) { 2045 if (kallsyms_filename != NULL) {
2039 machine__mmap_name(machine, path, sizeof(path)); 2046 machine__mmap_name(machine, path, sizeof(path));
2040 dso__set_long_name(self, strdup(path)); 2047 dso__set_long_name(dso, strdup(path));
2041 } 2048 }
2042 map__fixup_start(map); 2049 map__fixup_start(map);
2043 map__fixup_end(map); 2050 map__fixup_end(map);
@@ -2090,12 +2097,12 @@ size_t __dsos__fprintf(struct list_head *head, FILE *fp)
2090 return ret; 2097 return ret;
2091} 2098}
2092 2099
2093size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp) 2100size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp)
2094{ 2101{
2095 struct rb_node *nd; 2102 struct rb_node *nd;
2096 size_t ret = 0; 2103 size_t ret = 0;
2097 2104
2098 for (nd = rb_first(self); nd; nd = rb_next(nd)) { 2105 for (nd = rb_first(machines); nd; nd = rb_next(nd)) {
2099 struct machine *pos = rb_entry(nd, struct machine, rb_node); 2106 struct machine *pos = rb_entry(nd, struct machine, rb_node);
2100 ret += __dsos__fprintf(&pos->kernel_dsos, fp); 2107 ret += __dsos__fprintf(&pos->kernel_dsos, fp);
2101 ret += __dsos__fprintf(&pos->user_dsos, fp); 2108 ret += __dsos__fprintf(&pos->user_dsos, fp);
@@ -2119,18 +2126,20 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
2119 return ret; 2126 return ret;
2120} 2127}
2121 2128
2122size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits) 2129size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp,
2130 bool with_hits)
2123{ 2131{
2124 return __dsos__fprintf_buildid(&self->kernel_dsos, fp, with_hits) + 2132 return __dsos__fprintf_buildid(&machine->kernel_dsos, fp, with_hits) +
2125 __dsos__fprintf_buildid(&self->user_dsos, fp, with_hits); 2133 __dsos__fprintf_buildid(&machine->user_dsos, fp, with_hits);
2126} 2134}
2127 2135
2128size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits) 2136size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
2137 FILE *fp, bool with_hits)
2129{ 2138{
2130 struct rb_node *nd; 2139 struct rb_node *nd;
2131 size_t ret = 0; 2140 size_t ret = 0;
2132 2141
2133 for (nd = rb_first(self); nd; nd = rb_next(nd)) { 2142 for (nd = rb_first(machines); nd; nd = rb_next(nd)) {
2134 struct machine *pos = rb_entry(nd, struct machine, rb_node); 2143 struct machine *pos = rb_entry(nd, struct machine, rb_node);
2135 ret += machine__fprintf_dsos_buildid(pos, fp, with_hits); 2144 ret += machine__fprintf_dsos_buildid(pos, fp, with_hits);
2136 } 2145 }
@@ -2139,59 +2148,59 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_
2139 2148
2140struct dso *dso__new_kernel(const char *name) 2149struct dso *dso__new_kernel(const char *name)
2141{ 2150{
2142 struct dso *self = dso__new(name ?: "[kernel.kallsyms]"); 2151 struct dso *dso = dso__new(name ?: "[kernel.kallsyms]");
2143 2152
2144 if (self != NULL) { 2153 if (dso != NULL) {
2145 dso__set_short_name(self, "[kernel]"); 2154 dso__set_short_name(dso, "[kernel]");
2146 self->kernel = DSO_TYPE_KERNEL; 2155 dso->kernel = DSO_TYPE_KERNEL;
2147 } 2156 }
2148 2157
2149 return self; 2158 return dso;
2150} 2159}
2151 2160
2152static struct dso *dso__new_guest_kernel(struct machine *machine, 2161static struct dso *dso__new_guest_kernel(struct machine *machine,
2153 const char *name) 2162 const char *name)
2154{ 2163{
2155 char bf[PATH_MAX]; 2164 char bf[PATH_MAX];
2156 struct dso *self = dso__new(name ?: machine__mmap_name(machine, bf, sizeof(bf))); 2165 struct dso *dso = dso__new(name ?: machine__mmap_name(machine, bf,
2157 2166 sizeof(bf)));
2158 if (self != NULL) { 2167 if (dso != NULL) {
2159 dso__set_short_name(self, "[guest.kernel]"); 2168 dso__set_short_name(dso, "[guest.kernel]");
2160 self->kernel = DSO_TYPE_GUEST_KERNEL; 2169 dso->kernel = DSO_TYPE_GUEST_KERNEL;
2161 } 2170 }
2162 2171
2163 return self; 2172 return dso;
2164} 2173}
2165 2174
2166void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine) 2175void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
2167{ 2176{
2168 char path[PATH_MAX]; 2177 char path[PATH_MAX];
2169 2178
2170 if (machine__is_default_guest(machine)) 2179 if (machine__is_default_guest(machine))
2171 return; 2180 return;
2172 sprintf(path, "%s/sys/kernel/notes", machine->root_dir); 2181 sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
2173 if (sysfs__read_build_id(path, self->build_id, 2182 if (sysfs__read_build_id(path, dso->build_id,
2174 sizeof(self->build_id)) == 0) 2183 sizeof(dso->build_id)) == 0)
2175 self->has_build_id = true; 2184 dso->has_build_id = true;
2176} 2185}
2177 2186
2178static struct dso *machine__create_kernel(struct machine *self) 2187static struct dso *machine__create_kernel(struct machine *machine)
2179{ 2188{
2180 const char *vmlinux_name = NULL; 2189 const char *vmlinux_name = NULL;
2181 struct dso *kernel; 2190 struct dso *kernel;
2182 2191
2183 if (machine__is_host(self)) { 2192 if (machine__is_host(machine)) {
2184 vmlinux_name = symbol_conf.vmlinux_name; 2193 vmlinux_name = symbol_conf.vmlinux_name;
2185 kernel = dso__new_kernel(vmlinux_name); 2194 kernel = dso__new_kernel(vmlinux_name);
2186 } else { 2195 } else {
2187 if (machine__is_default_guest(self)) 2196 if (machine__is_default_guest(machine))
2188 vmlinux_name = symbol_conf.default_guest_vmlinux_name; 2197 vmlinux_name = symbol_conf.default_guest_vmlinux_name;
2189 kernel = dso__new_guest_kernel(self, vmlinux_name); 2198 kernel = dso__new_guest_kernel(machine, vmlinux_name);
2190 } 2199 }
2191 2200
2192 if (kernel != NULL) { 2201 if (kernel != NULL) {
2193 dso__read_running_kernel_build_id(kernel, self); 2202 dso__read_running_kernel_build_id(kernel, machine);
2194 dsos__add(&self->kernel_dsos, kernel); 2203 dsos__add(&machine->kernel_dsos, kernel);
2195 } 2204 }
2196 return kernel; 2205 return kernel;
2197} 2206}
@@ -2236,41 +2245,43 @@ static u64 machine__get_kernel_start_addr(struct machine *machine)
2236 return args.start; 2245 return args.start;
2237} 2246}
2238 2247
2239int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) 2248int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
2240{ 2249{
2241 enum map_type type; 2250 enum map_type type;
2242 u64 start = machine__get_kernel_start_addr(self); 2251 u64 start = machine__get_kernel_start_addr(machine);
2243 2252
2244 for (type = 0; type < MAP__NR_TYPES; ++type) { 2253 for (type = 0; type < MAP__NR_TYPES; ++type) {
2245 struct kmap *kmap; 2254 struct kmap *kmap;
2246 2255
2247 self->vmlinux_maps[type] = map__new2(start, kernel, type); 2256 machine->vmlinux_maps[type] = map__new2(start, kernel, type);
2248 if (self->vmlinux_maps[type] == NULL) 2257 if (machine->vmlinux_maps[type] == NULL)
2249 return -1; 2258 return -1;
2250 2259
2251 self->vmlinux_maps[type]->map_ip = 2260 machine->vmlinux_maps[type]->map_ip =
2252 self->vmlinux_maps[type]->unmap_ip = identity__map_ip; 2261 machine->vmlinux_maps[type]->unmap_ip =
2253 2262 identity__map_ip;
2254 kmap = map__kmap(self->vmlinux_maps[type]); 2263 kmap = map__kmap(machine->vmlinux_maps[type]);
2255 kmap->kmaps = &self->kmaps; 2264 kmap->kmaps = &machine->kmaps;
2256 map_groups__insert(&self->kmaps, self->vmlinux_maps[type]); 2265 map_groups__insert(&machine->kmaps,
2266 machine->vmlinux_maps[type]);
2257 } 2267 }
2258 2268
2259 return 0; 2269 return 0;
2260} 2270}
2261 2271
2262void machine__destroy_kernel_maps(struct machine *self) 2272void machine__destroy_kernel_maps(struct machine *machine)
2263{ 2273{
2264 enum map_type type; 2274 enum map_type type;
2265 2275
2266 for (type = 0; type < MAP__NR_TYPES; ++type) { 2276 for (type = 0; type < MAP__NR_TYPES; ++type) {
2267 struct kmap *kmap; 2277 struct kmap *kmap;
2268 2278
2269 if (self->vmlinux_maps[type] == NULL) 2279 if (machine->vmlinux_maps[type] == NULL)
2270 continue; 2280 continue;
2271 2281
2272 kmap = map__kmap(self->vmlinux_maps[type]); 2282 kmap = map__kmap(machine->vmlinux_maps[type]);
2273 map_groups__remove(&self->kmaps, self->vmlinux_maps[type]); 2283 map_groups__remove(&machine->kmaps,
2284 machine->vmlinux_maps[type]);
2274 if (kmap->ref_reloc_sym) { 2285 if (kmap->ref_reloc_sym) {
2275 /* 2286 /*
2276 * ref_reloc_sym is shared among all maps, so free just 2287 * ref_reloc_sym is shared among all maps, so free just
@@ -2284,25 +2295,25 @@ void machine__destroy_kernel_maps(struct machine *self)
2284 kmap->ref_reloc_sym = NULL; 2295 kmap->ref_reloc_sym = NULL;
2285 } 2296 }
2286 2297
2287 map__delete(self->vmlinux_maps[type]); 2298 map__delete(machine->vmlinux_maps[type]);
2288 self->vmlinux_maps[type] = NULL; 2299 machine->vmlinux_maps[type] = NULL;
2289 } 2300 }
2290} 2301}
2291 2302
2292int machine__create_kernel_maps(struct machine *self) 2303int machine__create_kernel_maps(struct machine *machine)
2293{ 2304{
2294 struct dso *kernel = machine__create_kernel(self); 2305 struct dso *kernel = machine__create_kernel(machine);
2295 2306
2296 if (kernel == NULL || 2307 if (kernel == NULL ||
2297 __machine__create_kernel_maps(self, kernel) < 0) 2308 __machine__create_kernel_maps(machine, kernel) < 0)
2298 return -1; 2309 return -1;
2299 2310
2300 if (symbol_conf.use_modules && machine__create_modules(self) < 0) 2311 if (symbol_conf.use_modules && machine__create_modules(machine) < 0)
2301 pr_debug("Problems creating module maps, continuing anyway...\n"); 2312 pr_debug("Problems creating module maps, continuing anyway...\n");
2302 /* 2313 /*
2303 * Now that we have all the maps created, just set the ->end of them: 2314 * Now that we have all the maps created, just set the ->end of them:
2304 */ 2315 */
2305 map_groups__fixup_end(&self->kmaps); 2316 map_groups__fixup_end(&machine->kmaps);
2306 return 0; 2317 return 0;
2307} 2318}
2308 2319
@@ -2366,11 +2377,11 @@ out_fail:
2366 return -1; 2377 return -1;
2367} 2378}
2368 2379
2369size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp) 2380size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp)
2370{ 2381{
2371 int i; 2382 int i;
2372 size_t printed = 0; 2383 size_t printed = 0;
2373 struct dso *kdso = self->vmlinux_maps[MAP__FUNCTION]->dso; 2384 struct dso *kdso = machine->vmlinux_maps[MAP__FUNCTION]->dso;
2374 2385
2375 if (kdso->has_build_id) { 2386 if (kdso->has_build_id) {
2376 char filename[PATH_MAX]; 2387 char filename[PATH_MAX];
@@ -2467,9 +2478,9 @@ void symbol__exit(void)
2467 symbol_conf.initialized = false; 2478 symbol_conf.initialized = false;
2468} 2479}
2469 2480
2470int machines__create_kernel_maps(struct rb_root *self, pid_t pid) 2481int machines__create_kernel_maps(struct rb_root *machines, pid_t pid)
2471{ 2482{
2472 struct machine *machine = machines__findnew(self, pid); 2483 struct machine *machine = machines__findnew(machines, pid);
2473 2484
2474 if (machine == NULL) 2485 if (machine == NULL)
2475 return -1; 2486 return -1;
@@ -2520,7 +2531,7 @@ char *strxfrchar(char *s, char from, char to)
2520 return s; 2531 return s;
2521} 2532}
2522 2533
2523int machines__create_guest_kernel_maps(struct rb_root *self) 2534int machines__create_guest_kernel_maps(struct rb_root *machines)
2524{ 2535{
2525 int ret = 0; 2536 int ret = 0;
2526 struct dirent **namelist = NULL; 2537 struct dirent **namelist = NULL;
@@ -2531,7 +2542,7 @@ int machines__create_guest_kernel_maps(struct rb_root *self)
2531 if (symbol_conf.default_guest_vmlinux_name || 2542 if (symbol_conf.default_guest_vmlinux_name ||
2532 symbol_conf.default_guest_modules || 2543 symbol_conf.default_guest_modules ||
2533 symbol_conf.default_guest_kallsyms) { 2544 symbol_conf.default_guest_kallsyms) {
2534 machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID); 2545 machines__create_kernel_maps(machines, DEFAULT_GUEST_KERNEL_ID);
2535 } 2546 }
2536 2547
2537 if (symbol_conf.guestmount) { 2548 if (symbol_conf.guestmount) {
@@ -2552,7 +2563,7 @@ int machines__create_guest_kernel_maps(struct rb_root *self)
2552 pr_debug("Can't access file %s\n", path); 2563 pr_debug("Can't access file %s\n", path);
2553 goto failure; 2564 goto failure;
2554 } 2565 }
2555 machines__create_kernel_maps(self, pid); 2566 machines__create_kernel_maps(machines, pid);
2556 } 2567 }
2557failure: 2568failure:
2558 free(namelist); 2569 free(namelist);
@@ -2561,23 +2572,23 @@ failure:
2561 return ret; 2572 return ret;
2562} 2573}
2563 2574
2564void machines__destroy_guest_kernel_maps(struct rb_root *self) 2575void machines__destroy_guest_kernel_maps(struct rb_root *machines)
2565{ 2576{
2566 struct rb_node *next = rb_first(self); 2577 struct rb_node *next = rb_first(machines);
2567 2578
2568 while (next) { 2579 while (next) {
2569 struct machine *pos = rb_entry(next, struct machine, rb_node); 2580 struct machine *pos = rb_entry(next, struct machine, rb_node);
2570 2581
2571 next = rb_next(&pos->rb_node); 2582 next = rb_next(&pos->rb_node);
2572 rb_erase(&pos->rb_node, self); 2583 rb_erase(&pos->rb_node, machines);
2573 machine__delete(pos); 2584 machine__delete(pos);
2574 } 2585 }
2575} 2586}
2576 2587
2577int machine__load_kallsyms(struct machine *self, const char *filename, 2588int machine__load_kallsyms(struct machine *machine, const char *filename,
2578 enum map_type type, symbol_filter_t filter) 2589 enum map_type type, symbol_filter_t filter)
2579{ 2590{
2580 struct map *map = self->vmlinux_maps[type]; 2591 struct map *map = machine->vmlinux_maps[type];
2581 int ret = dso__load_kallsyms(map->dso, filename, map, filter); 2592 int ret = dso__load_kallsyms(map->dso, filename, map, filter);
2582 2593
2583 if (ret > 0) { 2594 if (ret > 0) {
@@ -2587,16 +2598,16 @@ int machine__load_kallsyms(struct machine *self, const char *filename,
2587 * kernel, with modules between them, fixup the end of all 2598 * kernel, with modules between them, fixup the end of all
2588 * sections. 2599 * sections.
2589 */ 2600 */
2590 __map_groups__fixup_end(&self->kmaps, type); 2601 __map_groups__fixup_end(&machine->kmaps, type);
2591 } 2602 }
2592 2603
2593 return ret; 2604 return ret;
2594} 2605}
2595 2606
2596int machine__load_vmlinux_path(struct machine *self, enum map_type type, 2607int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
2597 symbol_filter_t filter) 2608 symbol_filter_t filter)
2598{ 2609{
2599 struct map *map = self->vmlinux_maps[type]; 2610 struct map *map = machine->vmlinux_maps[type];
2600 int ret = dso__load_vmlinux_path(map->dso, map, filter); 2611 int ret = dso__load_vmlinux_path(map->dso, map, filter);
2601 2612
2602 if (ret > 0) { 2613 if (ret > 0) {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 713b0b40cc4a..242de0101a86 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -62,7 +62,7 @@ struct symbol {
62 char name[0]; 62 char name[0];
63}; 63};
64 64
65void symbol__delete(struct symbol *self); 65void symbol__delete(struct symbol *sym);
66 66
67struct strlist; 67struct strlist;
68 68
@@ -96,9 +96,9 @@ struct symbol_conf {
96 96
97extern struct symbol_conf symbol_conf; 97extern struct symbol_conf symbol_conf;
98 98
99static inline void *symbol__priv(struct symbol *self) 99static inline void *symbol__priv(struct symbol *sym)
100{ 100{
101 return ((void *)self) - symbol_conf.priv_size; 101 return ((void *)sym) - symbol_conf.priv_size;
102} 102}
103 103
104struct ref_reloc_sym { 104struct ref_reloc_sym {
@@ -155,43 +155,45 @@ struct dso {
155 155
156struct dso *dso__new(const char *name); 156struct dso *dso__new(const char *name);
157struct dso *dso__new_kernel(const char *name); 157struct dso *dso__new_kernel(const char *name);
158void dso__delete(struct dso *self); 158void dso__delete(struct dso *dso);
159 159
160int dso__name_len(const struct dso *self); 160int dso__name_len(const struct dso *dso);
161 161
162bool dso__loaded(const struct dso *self, enum map_type type); 162bool dso__loaded(const struct dso *dso, enum map_type type);
163bool dso__sorted_by_name(const struct dso *self, enum map_type type); 163bool dso__sorted_by_name(const struct dso *dso, enum map_type type);
164 164
165static inline void dso__set_loaded(struct dso *self, enum map_type type) 165static inline void dso__set_loaded(struct dso *dso, enum map_type type)
166{ 166{
167 self->loaded |= (1 << type); 167 dso->loaded |= (1 << type);
168} 168}
169 169
170void dso__sort_by_name(struct dso *self, enum map_type type); 170void dso__sort_by_name(struct dso *dso, enum map_type type);
171 171
172struct dso *__dsos__findnew(struct list_head *head, const char *name); 172struct dso *__dsos__findnew(struct list_head *head, const char *name);
173 173
174int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); 174int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter);
175int dso__load_vmlinux(struct dso *self, struct map *map, 175int dso__load_vmlinux(struct dso *dso, struct map *map,
176 const char *vmlinux, symbol_filter_t filter); 176 const char *vmlinux, symbol_filter_t filter);
177int dso__load_vmlinux_path(struct dso *self, struct map *map, 177int dso__load_vmlinux_path(struct dso *dso, struct map *map,
178 symbol_filter_t filter); 178 symbol_filter_t filter);
179int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map, 179int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
180 symbol_filter_t filter); 180 symbol_filter_t filter);
181int machine__load_kallsyms(struct machine *self, const char *filename, 181int machine__load_kallsyms(struct machine *machine, const char *filename,
182 enum map_type type, symbol_filter_t filter); 182 enum map_type type, symbol_filter_t filter);
183int machine__load_vmlinux_path(struct machine *self, enum map_type type, 183int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
184 symbol_filter_t filter); 184 symbol_filter_t filter);
185 185
186size_t __dsos__fprintf(struct list_head *head, FILE *fp); 186size_t __dsos__fprintf(struct list_head *head, FILE *fp);
187 187
188size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits); 188size_t machine__fprintf_dsos_buildid(struct machine *machine,
189size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp); 189 FILE *fp, bool with_hits);
190size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits); 190size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp);
191 191size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
192size_t dso__fprintf_buildid(struct dso *self, FILE *fp); 192 FILE *fp, bool with_hits);
193size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp); 193size_t dso__fprintf_buildid(struct dso *dso, FILE *fp);
194size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); 194size_t dso__fprintf_symbols_by_name(struct dso *dso,
195 enum map_type type, FILE *fp);
196size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp);
195 197
196enum symtab_type { 198enum symtab_type {
197 SYMTAB__KALLSYMS = 0, 199 SYMTAB__KALLSYMS = 0,
@@ -207,34 +209,36 @@ enum symtab_type {
207 SYMTAB__NOT_FOUND, 209 SYMTAB__NOT_FOUND,
208}; 210};
209 211
210char dso__symtab_origin(const struct dso *self); 212char dso__symtab_origin(const struct dso *dso);
211void dso__set_long_name(struct dso *self, char *name); 213void dso__set_long_name(struct dso *dso, char *name);
212void dso__set_build_id(struct dso *self, void *build_id); 214void dso__set_build_id(struct dso *dso, void *build_id);
213void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine); 215void dso__read_running_kernel_build_id(struct dso *dso,
214struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); 216 struct machine *machine);
215struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type, 217struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
218 u64 addr);
219struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
216 const char *name); 220 const char *name);
217 221
218int filename__read_build_id(const char *filename, void *bf, size_t size); 222int filename__read_build_id(const char *filename, void *bf, size_t size);
219int sysfs__read_build_id(const char *filename, void *bf, size_t size); 223int sysfs__read_build_id(const char *filename, void *bf, size_t size);
220bool __dsos__read_build_ids(struct list_head *head, bool with_hits); 224bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
221int build_id__sprintf(const u8 *self, int len, char *bf); 225int build_id__sprintf(const u8 *build_id, int len, char *bf);
222int kallsyms__parse(const char *filename, void *arg, 226int kallsyms__parse(const char *filename, void *arg,
223 int (*process_symbol)(void *arg, const char *name, 227 int (*process_symbol)(void *arg, const char *name,
224 char type, u64 start, u64 end)); 228 char type, u64 start, u64 end));
225 229
226void machine__destroy_kernel_maps(struct machine *self); 230void machine__destroy_kernel_maps(struct machine *machine);
227int __machine__create_kernel_maps(struct machine *self, struct dso *kernel); 231int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel);
228int machine__create_kernel_maps(struct machine *self); 232int machine__create_kernel_maps(struct machine *machine);
229 233
230int machines__create_kernel_maps(struct rb_root *self, pid_t pid); 234int machines__create_kernel_maps(struct rb_root *machines, pid_t pid);
231int machines__create_guest_kernel_maps(struct rb_root *self); 235int machines__create_guest_kernel_maps(struct rb_root *machines);
232void machines__destroy_guest_kernel_maps(struct rb_root *self); 236void machines__destroy_guest_kernel_maps(struct rb_root *machines);
233 237
234int symbol__init(void); 238int symbol__init(void);
235void symbol__exit(void); 239void symbol__exit(void);
236bool symbol_type__is_a(char symbol_type, enum map_type map_type); 240bool symbol_type__is_a(char symbol_type, enum map_type map_type);
237 241
238size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp); 242size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);
239 243
240#endif /* __PERF_SYMBOL */ 244#endif /* __PERF_SYMBOL */
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 0a7ed5b5e281..1e88485c16a0 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -2187,7 +2187,6 @@ static const struct flag flags[] = {
2187 { "TASKLET_SOFTIRQ", 6 }, 2187 { "TASKLET_SOFTIRQ", 6 },
2188 { "SCHED_SOFTIRQ", 7 }, 2188 { "SCHED_SOFTIRQ", 7 },
2189 { "HRTIMER_SOFTIRQ", 8 }, 2189 { "HRTIMER_SOFTIRQ", 8 },
2190 { "RCU_SOFTIRQ", 9 },
2191 2190
2192 { "HRTIMER_NORESTART", 0 }, 2191 { "HRTIMER_NORESTART", 0 },
2193 { "HRTIMER_RESTART", 1 }, 2192 { "HRTIMER_RESTART", 1 },
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index 8ce792ea08e9..1fd29b2daa92 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -36,6 +36,7 @@ $default{"REBOOT_ON_SUCCESS"} = 1;
36$default{"POWEROFF_ON_SUCCESS"} = 0; 36$default{"POWEROFF_ON_SUCCESS"} = 0;
37$default{"BUILD_OPTIONS"} = ""; 37$default{"BUILD_OPTIONS"} = "";
38$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects 38$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
39$default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
39$default{"CLEAR_LOG"} = 0; 40$default{"CLEAR_LOG"} = 0;
40$default{"BISECT_MANUAL"} = 0; 41$default{"BISECT_MANUAL"} = 0;
41$default{"BISECT_SKIP"} = 1; 42$default{"BISECT_SKIP"} = 1;
@@ -96,6 +97,7 @@ my $monitor_pid;
96my $monitor_cnt = 0; 97my $monitor_cnt = 0;
97my $sleep_time; 98my $sleep_time;
98my $bisect_sleep_time; 99my $bisect_sleep_time;
100my $patchcheck_sleep_time;
99my $store_failures; 101my $store_failures;
100my $timeout; 102my $timeout;
101my $booted_timeout; 103my $booted_timeout;
@@ -112,6 +114,7 @@ my $successes = 0;
112 114
113my %entered_configs; 115my %entered_configs;
114my %config_help; 116my %config_help;
117my %variable;
115 118
116$config_help{"MACHINE"} = << "EOF" 119$config_help{"MACHINE"} = << "EOF"
117 The machine hostname that you will test. 120 The machine hostname that you will test.
@@ -260,6 +263,39 @@ sub get_ktest_configs {
260 } 263 }
261} 264}
262 265
266sub process_variables {
267 my ($value) = @_;
268 my $retval = "";
269
270 # We want to check for '\', and it is just easier
271 # to check the previous characet of '$' and not need
272 # to worry if '$' is the first character. By adding
273 # a space to $value, we can just check [^\\]\$ and
274 # it will still work.
275 $value = " $value";
276
277 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
278 my $begin = $1;
279 my $var = $2;
280 my $end = $3;
281 # append beginning of value to retval
282 $retval = "$retval$begin";
283 if (defined($variable{$var})) {
284 $retval = "$retval$variable{$var}";
285 } else {
286 # put back the origin piece.
287 $retval = "$retval\$\{$var\}";
288 }
289 $value = $end;
290 }
291 $retval = "$retval$value";
292
293 # remove the space added in the beginning
294 $retval =~ s/ //;
295
296 return "$retval"
297}
298
263sub set_value { 299sub set_value {
264 my ($lvalue, $rvalue) = @_; 300 my ($lvalue, $rvalue) = @_;
265 301
@@ -269,10 +305,22 @@ sub set_value {
269 if ($rvalue =~ /^\s*$/) { 305 if ($rvalue =~ /^\s*$/) {
270 delete $opt{$lvalue}; 306 delete $opt{$lvalue};
271 } else { 307 } else {
308 $rvalue = process_variables($rvalue);
272 $opt{$lvalue} = $rvalue; 309 $opt{$lvalue} = $rvalue;
273 } 310 }
274} 311}
275 312
313sub set_variable {
314 my ($lvalue, $rvalue) = @_;
315
316 if ($rvalue =~ /^\s*$/) {
317 delete $variable{$lvalue};
318 } else {
319 $rvalue = process_variables($rvalue);
320 $variable{$lvalue} = $rvalue;
321 }
322}
323
276sub read_config { 324sub read_config {
277 my ($config) = @_; 325 my ($config) = @_;
278 326
@@ -385,6 +433,22 @@ sub read_config {
385 $repeats{$val} = $repeat; 433 $repeats{$val} = $repeat;
386 } 434 }
387 } 435 }
436 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
437 next if ($skip);
438
439 my $lvalue = $1;
440 my $rvalue = $2;
441
442 # process config variables.
443 # Config variables are only active while reading the
444 # config and can be defined anywhere. They also ignore
445 # TEST_START and DEFAULTS, but are skipped if they are in
446 # on of these sections that have SKIP defined.
447 # The save variable can be
448 # defined multiple times and the new one simply overrides
449 # the prevous one.
450 set_variable($lvalue, $rvalue);
451
388 } else { 452 } else {
389 die "$name: $.: Garbage found in config\n$_"; 453 die "$name: $.: Garbage found in config\n$_";
390 } 454 }
@@ -838,6 +902,7 @@ sub monitor {
838 902
839 if ($stop_test_after > 0 && !$booted && !$bug) { 903 if ($stop_test_after > 0 && !$booted && !$bug) {
840 if (time - $monitor_start > $stop_test_after) { 904 if (time - $monitor_start > $stop_test_after) {
905 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
841 $done = 1; 906 $done = 1;
842 } 907 }
843 } 908 }
@@ -907,7 +972,7 @@ sub install {
907 return if (!defined($post_install)); 972 return if (!defined($post_install));
908 973
909 my $cp_post_install = $post_install; 974 my $cp_post_install = $post_install;
910 $cp_post_install = s/\$KERNEL_VERSION/$version/g; 975 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
911 run_command "$cp_post_install" or 976 run_command "$cp_post_install" or
912 dodie "Failed to run post install"; 977 dodie "Failed to run post install";
913} 978}
@@ -1247,14 +1312,14 @@ sub run_bisect_test {
1247 1312
1248 if ($failed) { 1313 if ($failed) {
1249 $result = 0; 1314 $result = 0;
1250
1251 # reboot the box to a good kernel
1252 if ($type ne "build") {
1253 bisect_reboot;
1254 }
1255 } else { 1315 } else {
1256 $result = 1; 1316 $result = 1;
1257 } 1317 }
1318
1319 # reboot the box to a kernel we can ssh to
1320 if ($type ne "build") {
1321 bisect_reboot;
1322 }
1258 $in_bisect = 0; 1323 $in_bisect = 0;
1259 1324
1260 return $result; 1325 return $result;
@@ -1763,6 +1828,14 @@ sub config_bisect {
1763 success $i; 1828 success $i;
1764} 1829}
1765 1830
1831sub patchcheck_reboot {
1832 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
1833 reboot;
1834 start_monitor;
1835 wait_for_monitor $patchcheck_sleep_time;
1836 end_monitor;
1837}
1838
1766sub patchcheck { 1839sub patchcheck {
1767 my ($i) = @_; 1840 my ($i) = @_;
1768 1841
@@ -1854,6 +1927,8 @@ sub patchcheck {
1854 end_monitor; 1927 end_monitor;
1855 return 0 if ($failed); 1928 return 0 if ($failed);
1856 1929
1930 patchcheck_reboot;
1931
1857 } 1932 }
1858 $in_patchcheck = 0; 1933 $in_patchcheck = 0;
1859 success $i; 1934 success $i;
@@ -1944,7 +2019,7 @@ for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1944 } 2019 }
1945} 2020}
1946 2021
1947sub set_test_option { 2022sub __set_test_option {
1948 my ($name, $i) = @_; 2023 my ($name, $i) = @_;
1949 2024
1950 my $option = "$name\[$i\]"; 2025 my $option = "$name\[$i\]";
@@ -1970,6 +2045,72 @@ sub set_test_option {
1970 return undef; 2045 return undef;
1971} 2046}
1972 2047
2048sub eval_option {
2049 my ($option, $i) = @_;
2050
2051 # Add space to evaluate the character before $
2052 $option = " $option";
2053 my $retval = "";
2054
2055 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
2056 my $start = $1;
2057 my $var = $2;
2058 my $end = $3;
2059
2060 # Append beginning of line
2061 $retval = "$retval$start";
2062
2063 # If the iteration option OPT[$i] exists, then use that.
2064 # otherwise see if the default OPT (without [$i]) exists.
2065
2066 my $o = "$var\[$i\]";
2067
2068 if (defined($opt{$o})) {
2069 $o = $opt{$o};
2070 $retval = "$retval$o";
2071 } elsif (defined($opt{$var})) {
2072 $o = $opt{$var};
2073 $retval = "$retval$o";
2074 } else {
2075 $retval = "$retval\$\{$var\}";
2076 }
2077
2078 $option = $end;
2079 }
2080
2081 $retval = "$retval$option";
2082
2083 $retval =~ s/^ //;
2084
2085 return $retval;
2086}
2087
2088sub set_test_option {
2089 my ($name, $i) = @_;
2090
2091 my $option = __set_test_option($name, $i);
2092 return $option if (!defined($option));
2093
2094 my $prev = "";
2095
2096 # Since an option can evaluate to another option,
2097 # keep iterating until we do not evaluate any more
2098 # options.
2099 my $r = 0;
2100 while ($prev ne $option) {
2101 # Check for recursive evaluations.
2102 # 100 deep should be more than enough.
2103 if ($r++ > 100) {
2104 die "Over 100 evaluations accurred with $name\n" .
2105 "Check for recursive variables\n";
2106 }
2107 $prev = $option;
2108 $option = eval_option($option, $i);
2109 }
2110
2111 return $option;
2112}
2113
1973# First we need to do is the builds 2114# First we need to do is the builds
1974for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 2115for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
1975 2116
@@ -2003,6 +2144,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2003 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); 2144 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
2004 $sleep_time = set_test_option("SLEEP_TIME", $i); 2145 $sleep_time = set_test_option("SLEEP_TIME", $i);
2005 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); 2146 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
2147 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
2006 $bisect_manual = set_test_option("BISECT_MANUAL", $i); 2148 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
2007 $bisect_skip = set_test_option("BISECT_SKIP", $i); 2149 $bisect_skip = set_test_option("BISECT_SKIP", $i);
2008 $store_failures = set_test_option("STORE_FAILURES", $i); 2150 $store_failures = set_test_option("STORE_FAILURES", $i);
diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf
index 4c5d6bd74a02..48cbcc80602a 100644
--- a/tools/testing/ktest/sample.conf
+++ b/tools/testing/ktest/sample.conf
@@ -73,6 +73,95 @@
73# ktest will fail to execute, and no tests will run. 73# ktest will fail to execute, and no tests will run.
74# 74#
75 75
76#### Config variables ####
77#
78# This config file can also contain "config variables".
79# These are assigned with ":=" instead of the ktest option
80# assigment "=".
81#
82# The difference between ktest options and config variables
83# is that config variables can be used multiple times,
84# where each instance will override the previous instance.
85# And that they only live at time of processing this config.
86#
87# The advantage to config variables are that they can be used
88# by any option or any other config variables to define thing
89# that you may use over and over again in the options.
90#
91# For example:
92#
93# USER := root
94# TARGET := mybox
95# TEST_CASE := ssh ${USER}@${TARGET} /path/to/my/test
96#
97# TEST_START
98# MIN_CONFIG = config1
99# TEST = ${TEST_CASE}
100#
101# TEST_START
102# MIN_CONFIG = config2
103# TEST = ${TEST_CASE}
104#
105# TEST_CASE := ssh ${USER}@${TARGET} /path/to/my/test2
106#
107# TEST_START
108# MIN_CONFIG = config1
109# TEST = ${TEST_CASE}
110#
111# TEST_START
112# MIN_CONFIG = config2
113# TEST = ${TEST_CASE}
114#
115# TEST_DIR := /home/me/test
116#
117# BUILD_DIR = ${TEST_DIR}/linux.git
118# OUTPUT_DIR = ${TEST_DIR}/test
119#
120# Note, the config variables are evaluated immediately, thus
121# updating TARGET after TEST_CASE has been assigned does nothing
122# to TEST_CASE.
123#
124# As shown in the example, to evaluate a config variable, you
125# use the ${X} convention. Simple $X will not work.
126#
127# If the config variable does not exist, the ${X} will not
128# be evaluated. Thus:
129#
130# MAKE_CMD = PATH=/mypath:${PATH} make
131#
132# If PATH is not a config variable, then the ${PATH} in
133# the MAKE_CMD option will be evaluated by the shell when
134# the MAKE_CMD option is passed into shell processing.
135
136#### Using options in other options ####
137#
138# Options that are defined in the config file may also be used
139# by other options. All options are evaulated at time of
140# use (except that config variables are evaluated at config
141# processing time).
142#
143# If an ktest option is used within another option, instead of
144# typing it again in that option you can simply use the option
145# just like you can config variables.
146#
147# MACHINE = mybox
148#
149# TEST = ssh root@${MACHINE} /path/to/test
150#
151# The option will be used per test case. Thus:
152#
153# TEST_TYPE = test
154# TEST = ssh root@{MACHINE}
155#
156# TEST_START
157# MACHINE = box1
158#
159# TEST_START
160# MACHINE = box2
161#
162# For both test cases, MACHINE will be evaluated at the time
163# of the test case. The first test will run ssh root@box1
164# and the second will run ssh root@box2.
76 165
77#### Mandatory Default Options #### 166#### Mandatory Default Options ####
78 167
@@ -366,6 +455,10 @@
366# (default 60) 455# (default 60)
367#BISECT_SLEEP_TIME = 60 456#BISECT_SLEEP_TIME = 60
368 457
458# The time in between patch checks to sleep (in seconds)
459# (default 60)
460#PATCHCHECK_SLEEP_TIME = 60
461
369# Reboot the target box on error (default 0) 462# Reboot the target box on error (default 0)
370#REBOOT_ON_ERROR = 0 463#REBOOT_ON_ERROR = 0
371 464