aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:38:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:38:34 -0400
commit619297855aa16646246ea4b1f6e05f1b2455c808 (patch)
treea07fe1b24c372f5eabf244555db41fdf574c1205 /tools
parente16b396ce314b2bcdfe6c173fe075bf8e3432368 (diff)
parent1ef1d1c2353967e2d61ecaddf76edfd058a778b4 (diff)
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (30 commits) trace, filters: Initialize the match variable in process_ops() properly trace, documentation: Fix branch profiling location in debugfs oprofile, s390: Cleanups oprofile, s390: Remove hwsampler_files.c and merge it into init.c perf: Fix tear-down of inherited group events perf: Reorder & optimize perf_event_context to remove alignment padding on 64 bit builds perf: Handle stopped state with tracepoints perf: Fix the software events state check perf, powerpc: Handle events that raise an exception without overflowing perf, x86: Use INTEL_*_CONSTRAINT() for all PEBS event constraints perf, x86: Clean up SandyBridge PEBS events perf lock: Fix sorting by wait_min perf tools: Version incorrect with some versions of grep perf evlist: New command to list the names of events present in a perf.data file perf script: Add support for H/W and S/W events perf script: Add support for dumping symbols perf script: Support custom field selection for output perf script: Move printing of 'common' data from print_event and rename perf tracing: Remove print_graph_cpu and print_graph_proc from trace-event-parse perf script: Change process_event prototype ...
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-evlist.txt26
-rw-r--r--tools/perf/Documentation/perf-script.txt22
-rw-r--r--tools/perf/Makefile1
-rw-r--r--tools/perf/builtin-evlist.c54
-rw-r--r--tools/perf/builtin-lock.c13
-rw-r--r--tools/perf/builtin-script.c300
-rw-r--r--tools/perf/builtin-stat.c8
-rw-r--r--tools/perf/builtin-top.c20
-rw-r--r--tools/perf/builtin.h1
-rw-r--r--tools/perf/command-list.txt1
-rw-r--r--tools/perf/perf.c1
-rwxr-xr-xtools/perf/util/PERF-VERSION-GEN8
-rw-r--r--tools/perf/util/annotate.c2
-rw-r--r--tools/perf/util/parse-events.c22
-rw-r--r--tools/perf/util/parse-events.h1
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c11
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c11
-rw-r--r--tools/perf/util/session.c61
-rw-r--r--tools/perf/util/session.h4
-rw-r--r--tools/perf/util/symbol.c64
-rw-r--r--tools/perf/util/symbol.h31
-rw-r--r--tools/perf/util/top.c6
-rw-r--r--tools/perf/util/top.h4
-rw-r--r--tools/perf/util/trace-event-parse.c110
-rw-r--r--tools/perf/util/trace-event-scripting.c9
-rw-r--r--tools/perf/util/trace-event.h10
26 files changed, 596 insertions, 205 deletions
diff --git a/tools/perf/Documentation/perf-evlist.txt b/tools/perf/Documentation/perf-evlist.txt
new file mode 100644
index 000000000000..0cada9e053dc
--- /dev/null
+++ b/tools/perf/Documentation/perf-evlist.txt
@@ -0,0 +1,26 @@
1perf-evlist(1)
2==============
3
4NAME
5----
6perf-evlist - List the event names in a perf.data file
7
8SYNOPSIS
9--------
10[verse]
11'perf evlist <options>'
12
13DESCRIPTION
14-----------
15This command displays the names of events sampled in a perf.data file.
16
17OPTIONS
18-------
19-i::
20--input=::
21 Input file name. (default: perf.data)
22
23SEE ALSO
24--------
25linkperf:perf-record[1], linkperf:perf-list[1],
26linkperf:perf-report[1]
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 29ad94293cd2..66f040b30729 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -112,6 +112,28 @@ OPTIONS
112--debug-mode:: 112--debug-mode::
113 Do various checks like samples ordering and lost events. 113 Do various checks like samples ordering and lost events.
114 114
115-f::
116--fields
117 Comma separated list of fields to print. Options are:
118 comm, tid, pid, time, cpu, event, trace, sym. Field
119 list must be prepended with the type, trace, sw or hw,
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
122
123-k::
124--vmlinux=<file>::
125 vmlinux pathname
126
127--kallsyms=<file>::
128 kallsyms pathname
129
130--symfs=<directory>::
131 Look for files with symbols relative to this directory.
132
133-G::
134--hide-call-graph::
135 When printing symbols do not display call chain.
136
115SEE ALSO 137SEE ALSO
116-------- 138--------
117linkperf:perf-record[1], linkperf:perf-script-perl[1], 139linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 9b8421805c5c..158c30e8210c 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -338,6 +338,7 @@ endif
338BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o 338BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
339 339
340BUILTIN_OBJS += $(OUTPUT)builtin-diff.o 340BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
341BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o
341BUILTIN_OBJS += $(OUTPUT)builtin-help.o 342BUILTIN_OBJS += $(OUTPUT)builtin-help.o
342BUILTIN_OBJS += $(OUTPUT)builtin-sched.o 343BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
343BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o 344BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
new file mode 100644
index 000000000000..4c5e9e04a41f
--- /dev/null
+++ b/tools/perf/builtin-evlist.c
@@ -0,0 +1,54 @@
1/*
2 * Builtin evlist command: Show the list of event selectors present
3 * in a perf.data file.
4 */
5#include "builtin.h"
6
7#include "util/util.h"
8
9#include <linux/list.h>
10
11#include "perf.h"
12#include "util/evlist.h"
13#include "util/evsel.h"
14#include "util/parse-events.h"
15#include "util/parse-options.h"
16#include "util/session.h"
17
18static char const *input_name = "perf.data";
19
20static int __cmd_evlist(void)
21{
22 struct perf_session *session;
23 struct perf_evsel *pos;
24
25 session = perf_session__new(input_name, O_RDONLY, 0, false, NULL);
26 if (session == NULL)
27 return -ENOMEM;
28
29 list_for_each_entry(pos, &session->evlist->entries, node)
30 printf("%s\n", event_name(pos));
31
32 perf_session__delete(session);
33 return 0;
34}
35
36static const char * const evlist_usage[] = {
37 "perf evlist [<options>]",
38 NULL
39};
40
41static const struct option options[] = {
42 OPT_STRING('i', "input", &input_name, "file",
43 "input file name"),
44 OPT_END()
45};
46
47int cmd_evlist(int argc, const char **argv, const char *prefix __used)
48{
49 argc = parse_options(argc, argv, options, evlist_usage, 0);
50 if (argc)
51 usage_with_options(evlist_usage, options);
52
53 return __cmd_evlist();
54}
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 2e93f99b1480..7a2a79d2cf2c 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -202,9 +202,20 @@ static struct thread_stat *thread_stat_findnew_first(u32 tid)
202SINGLE_KEY(nr_acquired) 202SINGLE_KEY(nr_acquired)
203SINGLE_KEY(nr_contended) 203SINGLE_KEY(nr_contended)
204SINGLE_KEY(wait_time_total) 204SINGLE_KEY(wait_time_total)
205SINGLE_KEY(wait_time_min)
206SINGLE_KEY(wait_time_max) 205SINGLE_KEY(wait_time_max)
207 206
207static int lock_stat_key_wait_time_min(struct lock_stat *one,
208 struct lock_stat *two)
209{
210 u64 s1 = one->wait_time_min;
211 u64 s2 = two->wait_time_min;
212 if (s1 == ULLONG_MAX)
213 s1 = 0;
214 if (s2 == ULLONG_MAX)
215 s2 = 0;
216 return s1 > s2;
217}
218
208struct lock_key { 219struct lock_key {
209 /* 220 /*
210 * name: the value for specify by user 221 * name: the value for specify by user
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 5f40df635dcb..9f5fc5492141 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -12,6 +12,8 @@
12#include "util/trace-event.h" 12#include "util/trace-event.h"
13#include "util/parse-options.h" 13#include "util/parse-options.h"
14#include "util/util.h" 14#include "util/util.h"
15#include "util/evlist.h"
16#include "util/evsel.h"
15 17
16static char const *script_name; 18static char const *script_name;
17static char const *generate_script_lang; 19static char const *generate_script_lang;
@@ -19,6 +21,183 @@ static bool debug_mode;
19static u64 last_timestamp; 21static u64 last_timestamp;
20static u64 nr_unordered; 22static u64 nr_unordered;
21extern const struct option record_options[]; 23extern const struct option record_options[];
24static bool no_callchain;
25
26enum perf_output_field {
27 PERF_OUTPUT_COMM = 1U << 0,
28 PERF_OUTPUT_TID = 1U << 1,
29 PERF_OUTPUT_PID = 1U << 2,
30 PERF_OUTPUT_TIME = 1U << 3,
31 PERF_OUTPUT_CPU = 1U << 4,
32 PERF_OUTPUT_EVNAME = 1U << 5,
33 PERF_OUTPUT_TRACE = 1U << 6,
34 PERF_OUTPUT_SYM = 1U << 7,
35};
36
37struct output_option {
38 const char *str;
39 enum perf_output_field field;
40} all_output_options[] = {
41 {.str = "comm", .field = PERF_OUTPUT_COMM},
42 {.str = "tid", .field = PERF_OUTPUT_TID},
43 {.str = "pid", .field = PERF_OUTPUT_PID},
44 {.str = "time", .field = PERF_OUTPUT_TIME},
45 {.str = "cpu", .field = PERF_OUTPUT_CPU},
46 {.str = "event", .field = PERF_OUTPUT_EVNAME},
47 {.str = "trace", .field = PERF_OUTPUT_TRACE},
48 {.str = "sym", .field = PERF_OUTPUT_SYM},
49};
50
51/* default set to maintain compatibility with current format */
52static u64 output_fields[PERF_TYPE_MAX] = {
53 [PERF_TYPE_HARDWARE] = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \
54 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \
55 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
56
57 [PERF_TYPE_SOFTWARE] = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \
58 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \
59 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
60
61 [PERF_TYPE_TRACEPOINT] = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \
62 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \
63 PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE,
64};
65
66static bool output_set_by_user;
67
68#define PRINT_FIELD(x) (output_fields[attr->type] & PERF_OUTPUT_##x)
69
70static int perf_session__check_attr(struct perf_session *session,
71 struct perf_event_attr *attr)
72{
73 if (PRINT_FIELD(TRACE) &&
74 !perf_session__has_traces(session, "record -R"))
75 return -EINVAL;
76
77 if (PRINT_FIELD(SYM)) {
78 if (!(session->sample_type & PERF_SAMPLE_IP)) {
79 pr_err("Samples do not contain IP data.\n");
80 return -EINVAL;
81 }
82 if (!no_callchain &&
83 !(session->sample_type & PERF_SAMPLE_CALLCHAIN))
84 symbol_conf.use_callchain = false;
85 }
86
87 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
88 !(session->sample_type & PERF_SAMPLE_TID)) {
89 pr_err("Samples do not contain TID/PID data.\n");
90 return -EINVAL;
91 }
92
93 if (PRINT_FIELD(TIME) &&
94 !(session->sample_type & PERF_SAMPLE_TIME)) {
95 pr_err("Samples do not contain timestamps.\n");
96 return -EINVAL;
97 }
98
99 if (PRINT_FIELD(CPU) &&
100 !(session->sample_type & PERF_SAMPLE_CPU)) {
101 pr_err("Samples do not contain cpu.\n");
102 return -EINVAL;
103 }
104
105 return 0;
106}
107
108static void print_sample_start(struct perf_sample *sample,
109 struct thread *thread,
110 struct perf_event_attr *attr)
111{
112 int type;
113 struct event *event;
114 const char *evname = NULL;
115 unsigned long secs;
116 unsigned long usecs;
117 unsigned long long nsecs;
118
119 if (PRINT_FIELD(COMM)) {
120 if (latency_format)
121 printf("%8.8s ", thread->comm);
122 else if (PRINT_FIELD(SYM) && symbol_conf.use_callchain)
123 printf("%s ", thread->comm);
124 else
125 printf("%16s ", thread->comm);
126 }
127
128 if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
129 printf("%5d/%-5d ", sample->pid, sample->tid);
130 else if (PRINT_FIELD(PID))
131 printf("%5d ", sample->pid);
132 else if (PRINT_FIELD(TID))
133 printf("%5d ", sample->tid);
134
135 if (PRINT_FIELD(CPU)) {
136 if (latency_format)
137 printf("%3d ", sample->cpu);
138 else
139 printf("[%03d] ", sample->cpu);
140 }
141
142 if (PRINT_FIELD(TIME)) {
143 nsecs = sample->time;
144 secs = nsecs / NSECS_PER_SEC;
145 nsecs -= secs * NSECS_PER_SEC;
146 usecs = nsecs / NSECS_PER_USEC;
147 printf("%5lu.%06lu: ", secs, usecs);
148 }
149
150 if (PRINT_FIELD(EVNAME)) {
151 if (attr->type == PERF_TYPE_TRACEPOINT) {
152 type = trace_parse_common_type(sample->raw_data);
153 event = trace_find_event(type);
154 if (event)
155 evname = event->name;
156 } else
157 evname = __event_name(attr->type, attr->config);
158
159 printf("%s: ", evname ? evname : "(unknown)");
160 }
161}
162
163static void process_event(union perf_event *event __unused,
164 struct perf_sample *sample,
165 struct perf_session *session,
166 struct thread *thread)
167{
168 struct perf_event_attr *attr;
169 struct perf_evsel *evsel;
170
171 evsel = perf_evlist__id2evsel(session->evlist, sample->id);
172 if (evsel == NULL) {
173 pr_err("Invalid data. Contains samples with id not in "
174 "its header!\n");
175 return;
176 }
177 attr = &evsel->attr;
178
179 if (output_fields[attr->type] == 0)
180 return;
181
182 if (perf_session__check_attr(session, attr) < 0)
183 return;
184
185 print_sample_start(sample, thread, attr);
186
187 if (PRINT_FIELD(TRACE))
188 print_trace_event(sample->cpu, sample->raw_data,
189 sample->raw_size);
190
191 if (PRINT_FIELD(SYM)) {
192 if (!symbol_conf.use_callchain)
193 printf(" ");
194 else
195 printf("\n");
196 perf_session__print_symbols(event, sample, session);
197 }
198
199 printf("\n");
200}
22 201
23static int default_start_script(const char *script __unused, 202static int default_start_script(const char *script __unused,
24 int argc __unused, 203 int argc __unused,
@@ -40,7 +219,7 @@ static int default_generate_script(const char *outfile __unused)
40static struct scripting_ops default_scripting_ops = { 219static struct scripting_ops default_scripting_ops = {
41 .start_script = default_start_script, 220 .start_script = default_start_script,
42 .stop_script = default_stop_script, 221 .stop_script = default_stop_script,
43 .process_event = print_event, 222 .process_event = process_event,
44 .generate_script = default_generate_script, 223 .generate_script = default_generate_script,
45}; 224};
46 225
@@ -75,26 +254,17 @@ static int process_sample_event(union perf_event *event,
75 return -1; 254 return -1;
76 } 255 }
77 256
78 if (session->sample_type & PERF_SAMPLE_RAW) { 257 if (debug_mode) {
79 if (debug_mode) { 258 if (sample->time < last_timestamp) {
80 if (sample->time < last_timestamp) { 259 pr_err("Samples misordered, previous: %" PRIu64
81 pr_err("Samples misordered, previous: %" PRIu64 260 " this: %" PRIu64 "\n", last_timestamp,
82 " this: %" PRIu64 "\n", last_timestamp, 261 sample->time);
83 sample->time); 262 nr_unordered++;
84 nr_unordered++;
85 }
86 last_timestamp = sample->time;
87 return 0;
88 } 263 }
89 /* 264 last_timestamp = sample->time;
90 * FIXME: better resolve from pid from the struct trace_entry 265 return 0;
91 * field, although it should be the same than this perf
92 * event pid
93 */
94 scripting_ops->process_event(sample->cpu, sample->raw_data,
95 sample->raw_size,
96 sample->time, thread->comm);
97 } 266 }
267 scripting_ops->process_event(event, sample, session, thread);
98 268
99 session->hists.stats.total_period += sample->period; 269 session->hists.stats.total_period += sample->period;
100 return 0; 270 return 0;
@@ -102,7 +272,10 @@ static int process_sample_event(union perf_event *event,
102 272
103static struct perf_event_ops event_ops = { 273static struct perf_event_ops event_ops = {
104 .sample = process_sample_event, 274 .sample = process_sample_event,
275 .mmap = perf_event__process_mmap,
105 .comm = perf_event__process_comm, 276 .comm = perf_event__process_comm,
277 .exit = perf_event__process_task,
278 .fork = perf_event__process_task,
106 .attr = perf_event__process_attr, 279 .attr = perf_event__process_attr,
107 .event_type = perf_event__process_event_type, 280 .event_type = perf_event__process_event_type,
108 .tracing_data = perf_event__process_tracing_data, 281 .tracing_data = perf_event__process_tracing_data,
@@ -280,6 +453,68 @@ static int parse_scriptname(const struct option *opt __used,
280 return 0; 453 return 0;
281} 454}
282 455
456static int parse_output_fields(const struct option *opt __used,
457 const char *arg, int unset __used)
458{
459 char *tok;
460 int i, imax = sizeof(all_output_options) / sizeof(struct output_option);
461 int rc = 0;
462 char *str = strdup(arg);
463 int type = -1;
464
465 if (!str)
466 return -ENOMEM;
467
468 tok = strtok(str, ":");
469 if (!tok) {
470 fprintf(stderr,
471 "Invalid field string - not prepended with type.");
472 return -EINVAL;
473 }
474
475 /* first word should state which event type user
476 * is specifying the fields
477 */
478 if (!strcmp(tok, "hw"))
479 type = PERF_TYPE_HARDWARE;
480 else if (!strcmp(tok, "sw"))
481 type = PERF_TYPE_SOFTWARE;
482 else if (!strcmp(tok, "trace"))
483 type = PERF_TYPE_TRACEPOINT;
484 else {
485 fprintf(stderr, "Invalid event type in field string.");
486 return -EINVAL;
487 }
488
489 output_fields[type] = 0;
490 while (1) {
491 tok = strtok(NULL, ",");
492 if (!tok)
493 break;
494 for (i = 0; i < imax; ++i) {
495 if (strcmp(tok, all_output_options[i].str) == 0) {
496 output_fields[type] |= all_output_options[i].field;
497 break;
498 }
499 }
500 if (i == imax) {
501 fprintf(stderr, "Invalid field requested.");
502 rc = -EINVAL;
503 break;
504 }
505 }
506
507 if (output_fields[type] == 0) {
508 pr_debug("No fields requested for %s type. "
509 "Events will not be displayed\n", event_type(type));
510 }
511
512 output_set_by_user = true;
513
514 free(str);
515 return rc;
516}
517
283/* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */ 518/* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */
284static int is_directory(const char *base_path, const struct dirent *dent) 519static int is_directory(const char *base_path, const struct dirent *dent)
285{ 520{
@@ -592,6 +827,17 @@ static const struct option options[] = {
592 "input file name"), 827 "input file name"),
593 OPT_BOOLEAN('d', "debug-mode", &debug_mode, 828 OPT_BOOLEAN('d', "debug-mode", &debug_mode,
594 "do various checks like samples ordering and lost events"), 829 "do various checks like samples ordering and lost events"),
830 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
831 "file", "vmlinux pathname"),
832 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
833 "file", "kallsyms pathname"),
834 OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
835 "When printing symbols do not display call chain"),
836 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
837 "Look for files with symbols relative to this directory"),
838 OPT_CALLBACK('f', "fields", NULL, "str",
839 "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace. Fields: comm,tid,pid,time,cpu,event,trace,sym",
840 parse_output_fields),
595 841
596 OPT_END() 842 OPT_END()
597}; 843};
@@ -772,14 +1018,22 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
772 if (session == NULL) 1018 if (session == NULL)
773 return -ENOMEM; 1019 return -ENOMEM;
774 1020
775 if (strcmp(input_name, "-") && 1021 if (!no_callchain)
776 !perf_session__has_traces(session, "record -R")) 1022 symbol_conf.use_callchain = true;
777 return -EINVAL; 1023 else
1024 symbol_conf.use_callchain = false;
778 1025
779 if (generate_script_lang) { 1026 if (generate_script_lang) {
780 struct stat perf_stat; 1027 struct stat perf_stat;
1028 int input;
1029
1030 if (output_set_by_user) {
1031 fprintf(stderr,
1032 "custom fields not supported for generated scripts");
1033 return -1;
1034 }
781 1035
782 int input = open(input_name, O_RDONLY); 1036 input = open(input_name, O_RDONLY);
783 if (input < 0) { 1037 if (input < 0) {
784 perror("failed to open file"); 1038 perror("failed to open file");
785 exit(-1); 1039 exit(-1);
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 21c025222496..e2109f9b43eb 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -333,6 +333,12 @@ static int run_perf_stat(int argc __used, const char **argv)
333 } 333 }
334 } 334 }
335 335
336 if (perf_evlist__set_filters(evsel_list)) {
337 error("failed to set filter with %d (%s)\n", errno,
338 strerror(errno));
339 return -1;
340 }
341
336 /* 342 /*
337 * Enable counters and exec the command: 343 * Enable counters and exec the command:
338 */ 344 */
@@ -634,6 +640,8 @@ static const struct option options[] = {
634 OPT_CALLBACK('e', "event", &evsel_list, "event", 640 OPT_CALLBACK('e', "event", &evsel_list, "event",
635 "event selector. use 'perf list' to list available events", 641 "event selector. use 'perf list' to list available events",
636 parse_events), 642 parse_events),
643 OPT_CALLBACK(0, "filter", &evsel_list, "filter",
644 "event filter", parse_filter),
637 OPT_BOOLEAN('i', "no-inherit", &no_inherit, 645 OPT_BOOLEAN('i', "no-inherit", &no_inherit,
638 "child tasks do not inherit counters"), 646 "child tasks do not inherit counters"),
639 OPT_INTEGER('p', "pid", &target_pid, 647 OPT_INTEGER('p', "pid", &target_pid,
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 80c9e062bd5b..70f1075cc5b0 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -152,7 +152,7 @@ static int parse_source(struct sym_entry *syme)
152 /* 152 /*
153 * We can't annotate with just /proc/kallsyms 153 * We can't annotate with just /proc/kallsyms
154 */ 154 */
155 if (map->dso->origin == DSO__ORIG_KERNEL) { 155 if (map->dso->symtab_type == SYMTAB__KALLSYMS) {
156 pr_err("Can't annotate %s: No vmlinux file was found in the " 156 pr_err("Can't annotate %s: No vmlinux file was found in the "
157 "path\n", sym->name); 157 "path\n", sym->name);
158 sleep(1); 158 sleep(1);
@@ -515,24 +515,25 @@ static void handle_keypress(struct perf_session *session, int c)
515 break; 515 break;
516 case 'E': 516 case 'E':
517 if (top.evlist->nr_entries > 1) { 517 if (top.evlist->nr_entries > 1) {
518 int counter;
518 fprintf(stderr, "\nAvailable events:"); 519 fprintf(stderr, "\nAvailable events:");
519 520
520 list_for_each_entry(top.sym_evsel, &top.evlist->entries, node) 521 list_for_each_entry(top.sym_evsel, &top.evlist->entries, node)
521 fprintf(stderr, "\n\t%d %s", top.sym_evsel->idx, event_name(top.sym_evsel)); 522 fprintf(stderr, "\n\t%d %s", top.sym_evsel->idx, event_name(top.sym_evsel));
522 523
523 prompt_integer(&top.sym_counter, "Enter details event counter"); 524 prompt_integer(&counter, "Enter details event counter");
524 525
525 if (top.sym_counter >= top.evlist->nr_entries) { 526 if (counter >= top.evlist->nr_entries) {
526 top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node); 527 top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
527 top.sym_counter = 0;
528 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(top.sym_evsel)); 528 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(top.sym_evsel));
529 sleep(1); 529 sleep(1);
530 break; 530 break;
531 } 531 }
532 list_for_each_entry(top.sym_evsel, &top.evlist->entries, node) 532 list_for_each_entry(top.sym_evsel, &top.evlist->entries, node)
533 if (top.sym_evsel->idx == top.sym_counter) 533 if (top.sym_evsel->idx == counter)
534 break; 534 break;
535 } else top.sym_counter = 0; 535 } else
536 top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
536 break; 537 break;
537 case 'f': 538 case 'f':
538 prompt_integer(&top.count_filter, "Enter display event count filter"); 539 prompt_integer(&top.count_filter, "Enter display event count filter");
@@ -675,7 +676,7 @@ static int symbol_filter(struct map *map, struct symbol *sym)
675 676
676 for (i = 0; skip_symbols[i]; i++) { 677 for (i = 0; skip_symbols[i]; i++) {
677 if (!strcmp(skip_symbols[i], name)) { 678 if (!strcmp(skip_symbols[i], name)) {
678 syme->skip = 1; 679 sym->ignore = true;
679 break; 680 break;
680 } 681 }
681 } 682 }
@@ -768,7 +769,7 @@ static void perf_event__process_sample(const union perf_event *event,
768 struct symbol *sym = sym_entry__symbol(top.sym_filter_entry); 769 struct symbol *sym = sym_entry__symbol(top.sym_filter_entry);
769 770
770 pr_err("Can't annotate %s", sym->name); 771 pr_err("Can't annotate %s", sym->name);
771 if (top.sym_filter_entry->map->dso->origin == DSO__ORIG_KERNEL) { 772 if (top.sym_filter_entry->map->dso->symtab_type == SYMTAB__KALLSYMS) {
772 pr_err(": No vmlinux file was found in the path:\n"); 773 pr_err(": No vmlinux file was found in the path:\n");
773 machine__fprintf_vmlinux_path(machine, stderr); 774 machine__fprintf_vmlinux_path(machine, stderr);
774 } else 775 } else
@@ -778,10 +779,9 @@ static void perf_event__process_sample(const union perf_event *event,
778 } 779 }
779 780
780 syme = symbol__priv(al.sym); 781 syme = symbol__priv(al.sym);
781 if (!syme->skip) { 782 if (!al.sym->ignore) {
782 struct perf_evsel *evsel; 783 struct perf_evsel *evsel;
783 784
784 syme->origin = origin;
785 evsel = perf_evlist__id2evsel(top.evlist, sample->id); 785 evsel = perf_evlist__id2evsel(top.evlist, sample->id);
786 assert(evsel != NULL); 786 assert(evsel != NULL);
787 syme->count[evsel->idx]++; 787 syme->count[evsel->idx]++;
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index c7798c7f24ed..4702e2443a8e 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -19,6 +19,7 @@ extern int cmd_bench(int argc, const char **argv, const char *prefix);
19extern int cmd_buildid_cache(int argc, const char **argv, const char *prefix); 19extern int cmd_buildid_cache(int argc, const char **argv, const char *prefix);
20extern int cmd_buildid_list(int argc, const char **argv, const char *prefix); 20extern int cmd_buildid_list(int argc, const char **argv, const char *prefix);
21extern int cmd_diff(int argc, const char **argv, const char *prefix); 21extern int cmd_diff(int argc, const char **argv, const char *prefix);
22extern int cmd_evlist(int argc, const char **argv, const char *prefix);
22extern int cmd_help(int argc, const char **argv, const char *prefix); 23extern int cmd_help(int argc, const char **argv, const char *prefix);
23extern int cmd_sched(int argc, const char **argv, const char *prefix); 24extern int cmd_sched(int argc, const char **argv, const char *prefix);
24extern int cmd_list(int argc, const char **argv, const char *prefix); 25extern int cmd_list(int argc, const char **argv, const char *prefix);
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index 16b5088cf8f4..d695fe40fbff 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -8,6 +8,7 @@ perf-bench mainporcelain common
8perf-buildid-cache mainporcelain common 8perf-buildid-cache mainporcelain common
9perf-buildid-list mainporcelain common 9perf-buildid-list mainporcelain common
10perf-diff mainporcelain common 10perf-diff mainporcelain common
11perf-evlist mainporcelain common
11perf-inject mainporcelain common 12perf-inject mainporcelain common
12perf-list mainporcelain common 13perf-list mainporcelain common
13perf-sched mainporcelain common 14perf-sched mainporcelain common
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 595d0f4a7103..ec635b7cc8ea 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -313,6 +313,7 @@ static void handle_internal_command(int argc, const char **argv)
313 { "buildid-cache", cmd_buildid_cache, 0 }, 313 { "buildid-cache", cmd_buildid_cache, 0 },
314 { "buildid-list", cmd_buildid_list, 0 }, 314 { "buildid-list", cmd_buildid_list, 0 },
315 { "diff", cmd_diff, 0 }, 315 { "diff", cmd_diff, 0 },
316 { "evlist", cmd_evlist, 0 },
316 { "help", cmd_help, 0 }, 317 { "help", cmd_help, 0 },
317 { "list", cmd_list, 0 }, 318 { "list", cmd_list, 0 },
318 { "record", cmd_record, 0 }, 319 { "record", cmd_record, 0 },
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN
index 97d76562a1a0..26d4d3fd6deb 100755
--- a/tools/perf/util/PERF-VERSION-GEN
+++ b/tools/perf/util/PERF-VERSION-GEN
@@ -23,10 +23,10 @@ if test -d ../../.git -o -f ../../.git &&
23then 23then
24 VN=$(echo "$VN" | sed -e 's/-/./g'); 24 VN=$(echo "$VN" | sed -e 's/-/./g');
25else 25else
26 eval `grep '^VERSION\s*=' ../../Makefile|tr -d ' '` 26 eval $(grep '^VERSION[[:space:]]*=' ../../Makefile|tr -d ' ')
27 eval `grep '^PATCHLEVEL\s*=' ../../Makefile|tr -d ' '` 27 eval $(grep '^PATCHLEVEL[[:space:]]*=' ../../Makefile|tr -d ' ')
28 eval `grep '^SUBLEVEL\s*=' ../../Makefile|tr -d ' '` 28 eval $(grep '^SUBLEVEL[[:space:]]*=' ../../Makefile|tr -d ' ')
29 eval `grep '^EXTRAVERSION\s*=' ../../Makefile|tr -d ' '` 29 eval $(grep '^EXTRAVERSION[[:space:]]*=' ../../Makefile|tr -d ' ')
30 30
31 VN="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}" 31 VN="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}"
32fi 32fi
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 0d0830c98cd7..e01af2b1a469 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -294,7 +294,7 @@ fallback:
294 free_filename = false; 294 free_filename = false;
295 } 295 }
296 296
297 if (dso->origin == DSO__ORIG_KERNEL) { 297 if (dso->symtab_type == SYMTAB__KALLSYMS) {
298 char bf[BUILD_ID_SIZE * 2 + 16] = " with build id "; 298 char bf[BUILD_ID_SIZE * 2 + 16] = " with build id ";
299 char *build_id_msg = NULL; 299 char *build_id_msg = NULL;
300 300
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 54a7e2634d58..952b4ae3d954 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -263,6 +263,28 @@ static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
263 return name; 263 return name;
264} 264}
265 265
266const char *event_type(int type)
267{
268 switch (type) {
269 case PERF_TYPE_HARDWARE:
270 return "hardware";
271
272 case PERF_TYPE_SOFTWARE:
273 return "software";
274
275 case PERF_TYPE_TRACEPOINT:
276 return "tracepoint";
277
278 case PERF_TYPE_HW_CACHE:
279 return "hardware-cache";
280
281 default:
282 break;
283 }
284
285 return "unknown";
286}
287
266const char *event_name(struct perf_evsel *evsel) 288const char *event_name(struct perf_evsel *evsel)
267{ 289{
268 u64 config = evsel->attr.config; 290 u64 config = evsel->attr.config;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 212f88e07a9c..746d3fcbfc2a 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -20,6 +20,7 @@ struct tracepoint_path {
20extern struct tracepoint_path *tracepoint_id_to_path(u64 config); 20extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
21extern bool have_tracepoints(struct list_head *evlist); 21extern bool have_tracepoints(struct list_head *evlist);
22 22
23const char *event_type(int type);
23const char *event_name(struct perf_evsel *event); 24const char *event_name(struct perf_evsel *event);
24extern const char *__event_name(int type, u64 config); 25extern const char *__event_name(int type, u64 config);
25 26
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 93680818e244..621427212e86 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -245,9 +245,10 @@ static inline struct event *find_cache_event(int type)
245 return event; 245 return event;
246} 246}
247 247
248static void perl_process_event(int cpu, void *data, 248static void perl_process_event(union perf_event *pevent __unused,
249 int size __unused, 249 struct perf_sample *sample,
250 unsigned long long nsecs, char *comm) 250 struct perf_session *session __unused,
251 struct thread *thread)
251{ 252{
252 struct format_field *field; 253 struct format_field *field;
253 static char handler[256]; 254 static char handler[256];
@@ -256,6 +257,10 @@ static void perl_process_event(int cpu, void *data,
256 struct event *event; 257 struct event *event;
257 int type; 258 int type;
258 int pid; 259 int pid;
260 int cpu = sample->cpu;
261 void *data = sample->raw_data;
262 unsigned long long nsecs = sample->time;
263 char *comm = thread->comm;
259 264
260 dSP; 265 dSP;
261 266
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 2040b8538527..1b85d6055159 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -204,9 +204,10 @@ static inline struct event *find_cache_event(int type)
204 return event; 204 return event;
205} 205}
206 206
207static void python_process_event(int cpu, void *data, 207static void python_process_event(union perf_event *pevent __unused,
208 int size __unused, 208 struct perf_sample *sample,
209 unsigned long long nsecs, char *comm) 209 struct perf_session *session __unused,
210 struct thread *thread)
210{ 211{
211 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; 212 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
212 static char handler_name[256]; 213 static char handler_name[256];
@@ -217,6 +218,10 @@ static void python_process_event(int cpu, void *data,
217 unsigned n = 0; 218 unsigned n = 0;
218 int type; 219 int type;
219 int pid; 220 int pid;
221 int cpu = sample->cpu;
222 void *data = sample->raw_data;
223 unsigned long long nsecs = sample->time;
224 char *comm = thread->comm;
220 225
221 t = PyTuple_New(MAX_FIELDS); 226 t = PyTuple_New(MAX_FIELDS);
222 if (!t) 227 if (!t)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index f26639fa0fb3..c68cf40764f9 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1134,3 +1134,64 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
1134 1134
1135 return ret; 1135 return ret;
1136} 1136}
1137
1138void perf_session__print_symbols(union perf_event *event,
1139 struct perf_sample *sample,
1140 struct perf_session *session)
1141{
1142 struct addr_location al;
1143 const char *symname, *dsoname;
1144 struct callchain_cursor *cursor = &session->callchain_cursor;
1145 struct callchain_cursor_node *node;
1146
1147 if (perf_event__preprocess_sample(event, session, &al, sample,
1148 NULL) < 0) {
1149 error("problem processing %d event, skipping it.\n",
1150 event->header.type);
1151 return;
1152 }
1153
1154 if (symbol_conf.use_callchain && sample->callchain) {
1155
1156 if (perf_session__resolve_callchain(session, al.thread,
1157 sample->callchain, NULL) != 0) {
1158 if (verbose)
1159 error("Failed to resolve callchain. Skipping\n");
1160 return;
1161 }
1162 callchain_cursor_commit(cursor);
1163
1164 while (1) {
1165 node = callchain_cursor_current(cursor);
1166 if (!node)
1167 break;
1168
1169 if (node->sym && node->sym->name)
1170 symname = node->sym->name;
1171 else
1172 symname = "";
1173
1174 if (node->map && node->map->dso && node->map->dso->name)
1175 dsoname = node->map->dso->name;
1176 else
1177 dsoname = "";
1178
1179 printf("\t%16" PRIx64 " %s (%s)\n", node->ip, symname, dsoname);
1180
1181 callchain_cursor_advance(cursor);
1182 }
1183
1184 } else {
1185 if (al.sym && al.sym->name)
1186 symname = al.sym->name;
1187 else
1188 symname = "";
1189
1190 if (al.map && al.map->dso && al.map->dso->name)
1191 dsoname = al.map->dso->name;
1192 else
1193 dsoname = "";
1194
1195 printf("%16" PRIx64 " %s (%s)", al.addr, symname, dsoname);
1196 }
1197}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index b5b148b0aaca..0b3c9afecaa9 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -159,4 +159,8 @@ static inline int perf_session__parse_sample(struct perf_session *session,
159 session->sample_id_all, sample); 159 session->sample_id_all, sample);
160} 160}
161 161
162void perf_session__print_symbols(union perf_event *event,
163 struct perf_sample *sample,
164 struct perf_session *session);
165
162#endif /* __PERF_SESSION_H */ 166#endif /* __PERF_SESSION_H */
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 00014e32c288..651dbfe7f4f3 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -207,7 +207,7 @@ struct dso *dso__new(const char *name)
207 dso__set_short_name(self, self->name); 207 dso__set_short_name(self, self->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 self->symbols[i] = self->symbol_names[i] = RB_ROOT;
210 self->origin = DSO__ORIG_NOT_FOUND; 210 self->symtab_type = SYMTAB__NOT_FOUND;
211 self->loaded = 0; 211 self->loaded = 0;
212 self->sorted_by_name = 0; 212 self->sorted_by_name = 0;
213 self->has_build_id = 0; 213 self->has_build_id = 0;
@@ -680,9 +680,9 @@ int dso__load_kallsyms(struct dso *self, const char *filename,
680 return -1; 680 return -1;
681 681
682 if (self->kernel == DSO_TYPE_GUEST_KERNEL) 682 if (self->kernel == DSO_TYPE_GUEST_KERNEL)
683 self->origin = DSO__ORIG_GUEST_KERNEL; 683 self->symtab_type = SYMTAB__GUEST_KALLSYMS;
684 else 684 else
685 self->origin = DSO__ORIG_KERNEL; 685 self->symtab_type = SYMTAB__KALLSYMS;
686 686
687 return dso__split_kallsyms(self, map, filter); 687 return dso__split_kallsyms(self, map, filter);
688} 688}
@@ -1204,7 +1204,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1204 } 1204 }
1205 curr_map->map_ip = identity__map_ip; 1205 curr_map->map_ip = identity__map_ip;
1206 curr_map->unmap_ip = identity__map_ip; 1206 curr_map->unmap_ip = identity__map_ip;
1207 curr_dso->origin = self->origin; 1207 curr_dso->symtab_type = self->symtab_type;
1208 map_groups__insert(kmap->kmaps, curr_map); 1208 map_groups__insert(kmap->kmaps, curr_map);
1209 dsos__add(&self->node, curr_dso); 1209 dsos__add(&self->node, curr_dso);
1210 dso__set_loaded(curr_dso, map->type); 1210 dso__set_loaded(curr_dso, map->type);
@@ -1430,21 +1430,21 @@ out:
1430char dso__symtab_origin(const struct dso *self) 1430char dso__symtab_origin(const struct dso *self)
1431{ 1431{
1432 static const char origin[] = { 1432 static const char origin[] = {
1433 [DSO__ORIG_KERNEL] = 'k', 1433 [SYMTAB__KALLSYMS] = 'k',
1434 [DSO__ORIG_JAVA_JIT] = 'j', 1434 [SYMTAB__JAVA_JIT] = 'j',
1435 [DSO__ORIG_BUILD_ID_CACHE] = 'B', 1435 [SYMTAB__BUILD_ID_CACHE] = 'B',
1436 [DSO__ORIG_FEDORA] = 'f', 1436 [SYMTAB__FEDORA_DEBUGINFO] = 'f',
1437 [DSO__ORIG_UBUNTU] = 'u', 1437 [SYMTAB__UBUNTU_DEBUGINFO] = 'u',
1438 [DSO__ORIG_BUILDID] = 'b', 1438 [SYMTAB__BUILDID_DEBUGINFO] = 'b',
1439 [DSO__ORIG_DSO] = 'd', 1439 [SYMTAB__SYSTEM_PATH_DSO] = 'd',
1440 [DSO__ORIG_KMODULE] = 'K', 1440 [SYMTAB__SYSTEM_PATH_KMODULE] = 'K',
1441 [DSO__ORIG_GUEST_KERNEL] = 'g', 1441 [SYMTAB__GUEST_KALLSYMS] = 'g',
1442 [DSO__ORIG_GUEST_KMODULE] = 'G', 1442 [SYMTAB__GUEST_KMODULE] = 'G',
1443 }; 1443 };
1444 1444
1445 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) 1445 if (self == NULL || self->symtab_type == SYMTAB__NOT_FOUND)
1446 return '!'; 1446 return '!';
1447 return origin[self->origin]; 1447 return origin[self->symtab_type];
1448} 1448}
1449 1449
1450int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) 1450int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
@@ -1477,8 +1477,8 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1477 1477
1478 if (strncmp(self->name, "/tmp/perf-", 10) == 0) { 1478 if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
1479 ret = dso__load_perf_map(self, map, filter); 1479 ret = dso__load_perf_map(self, map, filter);
1480 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : 1480 self->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT :
1481 DSO__ORIG_NOT_FOUND; 1481 SYMTAB__NOT_FOUND;
1482 return ret; 1482 return ret;
1483 } 1483 }
1484 1484
@@ -1486,26 +1486,26 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1486 * On the first pass, only load images if they have a full symtab. 1486 * On the first pass, only load images if they have a full symtab.
1487 * Failing that, do a second pass where we accept .dynsym also 1487 * Failing that, do a second pass where we accept .dynsym also
1488 */ 1488 */
1489 for (self->origin = DSO__ORIG_BUILD_ID_CACHE, want_symtab = 1; 1489 for (self->symtab_type = SYMTAB__BUILD_ID_CACHE, want_symtab = 1;
1490 self->origin != DSO__ORIG_NOT_FOUND; 1490 self->symtab_type != SYMTAB__NOT_FOUND;
1491 self->origin++) { 1491 self->symtab_type++) {
1492 switch (self->origin) { 1492 switch (self->symtab_type) {
1493 case DSO__ORIG_BUILD_ID_CACHE: 1493 case SYMTAB__BUILD_ID_CACHE:
1494 /* skip the locally configured cache if a symfs is given */ 1494 /* skip the locally configured cache if a symfs is given */
1495 if (symbol_conf.symfs[0] || 1495 if (symbol_conf.symfs[0] ||
1496 (dso__build_id_filename(self, name, size) == NULL)) { 1496 (dso__build_id_filename(self, name, size) == NULL)) {
1497 continue; 1497 continue;
1498 } 1498 }
1499 break; 1499 break;
1500 case DSO__ORIG_FEDORA: 1500 case SYMTAB__FEDORA_DEBUGINFO:
1501 snprintf(name, size, "%s/usr/lib/debug%s.debug", 1501 snprintf(name, size, "%s/usr/lib/debug%s.debug",
1502 symbol_conf.symfs, self->long_name); 1502 symbol_conf.symfs, self->long_name);
1503 break; 1503 break;
1504 case DSO__ORIG_UBUNTU: 1504 case SYMTAB__UBUNTU_DEBUGINFO:
1505 snprintf(name, size, "%s/usr/lib/debug%s", 1505 snprintf(name, size, "%s/usr/lib/debug%s",
1506 symbol_conf.symfs, self->long_name); 1506 symbol_conf.symfs, self->long_name);
1507 break; 1507 break;
1508 case DSO__ORIG_BUILDID: { 1508 case SYMTAB__BUILDID_DEBUGINFO: {
1509 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 1509 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1510 1510
1511 if (!self->has_build_id) 1511 if (!self->has_build_id)
@@ -1519,11 +1519,11 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1519 symbol_conf.symfs, build_id_hex, build_id_hex + 2); 1519 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
1520 } 1520 }
1521 break; 1521 break;
1522 case DSO__ORIG_DSO: 1522 case SYMTAB__SYSTEM_PATH_DSO:
1523 snprintf(name, size, "%s%s", 1523 snprintf(name, size, "%s%s",
1524 symbol_conf.symfs, self->long_name); 1524 symbol_conf.symfs, self->long_name);
1525 break; 1525 break;
1526 case DSO__ORIG_GUEST_KMODULE: 1526 case SYMTAB__GUEST_KMODULE:
1527 if (map->groups && machine) 1527 if (map->groups && machine)
1528 root_dir = machine->root_dir; 1528 root_dir = machine->root_dir;
1529 else 1529 else
@@ -1532,7 +1532,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1532 root_dir, self->long_name); 1532 root_dir, self->long_name);
1533 break; 1533 break;
1534 1534
1535 case DSO__ORIG_KMODULE: 1535 case SYMTAB__SYSTEM_PATH_KMODULE:
1536 snprintf(name, size, "%s%s", symbol_conf.symfs, 1536 snprintf(name, size, "%s%s", symbol_conf.symfs,
1537 self->long_name); 1537 self->long_name);
1538 break; 1538 break;
@@ -1544,7 +1544,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1544 */ 1544 */
1545 if (want_symtab) { 1545 if (want_symtab) {
1546 want_symtab = 0; 1546 want_symtab = 0;
1547 self->origin = DSO__ORIG_BUILD_ID_CACHE; 1547 self->symtab_type = SYMTAB__BUILD_ID_CACHE;
1548 } else 1548 } else
1549 continue; 1549 continue;
1550 } 1550 }
@@ -1757,9 +1757,9 @@ struct map *machine__new_module(struct machine *self, u64 start,
1757 return NULL; 1757 return NULL;
1758 1758
1759 if (machine__is_host(self)) 1759 if (machine__is_host(self))
1760 dso->origin = DSO__ORIG_KMODULE; 1760 dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE;
1761 else 1761 else
1762 dso->origin = DSO__ORIG_GUEST_KMODULE; 1762 dso->symtab_type = SYMTAB__GUEST_KMODULE;
1763 map_groups__insert(&self->kmaps, map); 1763 map_groups__insert(&self->kmaps, map);
1764 return map; 1764 return map;
1765} 1765}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 4d7ed09fe332..713b0b40cc4a 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -48,12 +48,17 @@ char *strxfrchar(char *s, char from, char to);
48 48
49#define BUILD_ID_SIZE 20 49#define BUILD_ID_SIZE 20
50 50
51/** struct symbol - symtab entry
52 *
53 * @ignore - resolvable but tools ignore it (e.g. idle routines)
54 */
51struct symbol { 55struct symbol {
52 struct rb_node rb_node; 56 struct rb_node rb_node;
53 u64 start; 57 u64 start;
54 u64 end; 58 u64 end;
55 u16 namelen; 59 u16 namelen;
56 u8 binding; 60 u8 binding;
61 bool ignore;
57 char name[0]; 62 char name[0];
58}; 63};
59 64
@@ -137,7 +142,7 @@ struct dso {
137 u8 annotate_warned:1; 142 u8 annotate_warned:1;
138 u8 sname_alloc:1; 143 u8 sname_alloc:1;
139 u8 lname_alloc:1; 144 u8 lname_alloc:1;
140 unsigned char origin; 145 unsigned char symtab_type;
141 u8 sorted_by_name; 146 u8 sorted_by_name;
142 u8 loaded; 147 u8 loaded;
143 u8 build_id[BUILD_ID_SIZE]; 148 u8 build_id[BUILD_ID_SIZE];
@@ -188,18 +193,18 @@ size_t dso__fprintf_buildid(struct dso *self, FILE *fp);
188size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp); 193size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp);
189size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); 194size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp);
190 195
191enum dso_origin { 196enum symtab_type {
192 DSO__ORIG_KERNEL = 0, 197 SYMTAB__KALLSYMS = 0,
193 DSO__ORIG_GUEST_KERNEL, 198 SYMTAB__GUEST_KALLSYMS,
194 DSO__ORIG_JAVA_JIT, 199 SYMTAB__JAVA_JIT,
195 DSO__ORIG_BUILD_ID_CACHE, 200 SYMTAB__BUILD_ID_CACHE,
196 DSO__ORIG_FEDORA, 201 SYMTAB__FEDORA_DEBUGINFO,
197 DSO__ORIG_UBUNTU, 202 SYMTAB__UBUNTU_DEBUGINFO,
198 DSO__ORIG_BUILDID, 203 SYMTAB__BUILDID_DEBUGINFO,
199 DSO__ORIG_DSO, 204 SYMTAB__SYSTEM_PATH_DSO,
200 DSO__ORIG_GUEST_KMODULE, 205 SYMTAB__GUEST_KMODULE,
201 DSO__ORIG_KMODULE, 206 SYMTAB__SYSTEM_PATH_KMODULE,
202 DSO__ORIG_NOT_FOUND, 207 SYMTAB__NOT_FOUND,
203}; 208};
204 209
205char dso__symtab_origin(const struct dso *self); 210char dso__symtab_origin(const struct dso *self);
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index 75cfe4d45119..a11f60735a18 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -171,7 +171,7 @@ float perf_top__decay_samples(struct perf_top *top, struct rb_root *root)
171{ 171{
172 struct sym_entry *syme, *n; 172 struct sym_entry *syme, *n;
173 float sum_ksamples = 0.0; 173 float sum_ksamples = 0.0;
174 int snap = !top->display_weighted ? top->sym_counter : 0, j; 174 int snap = !top->display_weighted ? top->sym_evsel->idx : 0, j;
175 175
176 /* Sort the active symbols */ 176 /* Sort the active symbols */
177 pthread_mutex_lock(&top->active_symbols_lock); 177 pthread_mutex_lock(&top->active_symbols_lock);
@@ -184,9 +184,9 @@ float perf_top__decay_samples(struct perf_top *top, struct rb_root *root)
184 if (syme->snap_count != 0) { 184 if (syme->snap_count != 0) {
185 185
186 if ((top->hide_user_symbols && 186 if ((top->hide_user_symbols &&
187 syme->origin == PERF_RECORD_MISC_USER) || 187 syme->map->dso->kernel == DSO_TYPE_USER) ||
188 (top->hide_kernel_symbols && 188 (top->hide_kernel_symbols &&
189 syme->origin == PERF_RECORD_MISC_KERNEL)) { 189 syme->map->dso->kernel == DSO_TYPE_KERNEL)) {
190 perf_top__remove_active_sym(top, syme); 190 perf_top__remove_active_sym(top, syme);
191 continue; 191 continue;
192 } 192 }
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index 96d1cb78af01..bfbf95bcc603 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -16,8 +16,6 @@ struct sym_entry {
16 struct list_head node; 16 struct list_head node;
17 unsigned long snap_count; 17 unsigned long snap_count;
18 double weight; 18 double weight;
19 int skip;
20 u8 origin;
21 struct map *map; 19 struct map *map;
22 unsigned long count[0]; 20 unsigned long count[0];
23}; 21};
@@ -41,7 +39,7 @@ struct perf_top {
41 u64 exact_samples; 39 u64 exact_samples;
42 u64 guest_us_samples, guest_kernel_samples; 40 u64 guest_us_samples, guest_kernel_samples;
43 int print_entries, count_filter, delay_secs; 41 int print_entries, count_filter, delay_secs;
44 int display_weighted, freq, rb_entries, sym_counter; 42 int display_weighted, freq, rb_entries;
45 pid_t target_pid, target_tid; 43 pid_t target_pid, target_tid;
46 bool hide_kernel_symbols, hide_user_symbols, zero; 44 bool hide_kernel_symbols, hide_user_symbols, zero;
47 const char *cpu_list; 45 const char *cpu_list;
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index d8e622dd738a..0a7ed5b5e281 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -2643,68 +2643,13 @@ static void print_lat_fmt(void *data, int size __unused)
2643 printf("."); 2643 printf(".");
2644 2644
2645 if (lock_depth < 0) 2645 if (lock_depth < 0)
2646 printf("."); 2646 printf(". ");
2647 else 2647 else
2648 printf("%d", lock_depth); 2648 printf("%d ", lock_depth);
2649} 2649}
2650 2650
2651/* taken from Linux, written by Frederic Weisbecker */
2652static void print_graph_cpu(int cpu)
2653{
2654 int i;
2655 int log10_this = log10_cpu(cpu);
2656 int log10_all = log10_cpu(cpus);
2657
2658
2659 /*
2660 * Start with a space character - to make it stand out
2661 * to the right a bit when trace output is pasted into
2662 * email:
2663 */
2664 printf(" ");
2665
2666 /*
2667 * Tricky - we space the CPU field according to the max
2668 * number of online CPUs. On a 2-cpu system it would take
2669 * a maximum of 1 digit - on a 128 cpu system it would
2670 * take up to 3 digits:
2671 */
2672 for (i = 0; i < log10_all - log10_this; i++)
2673 printf(" ");
2674
2675 printf("%d) ", cpu);
2676}
2677
2678#define TRACE_GRAPH_PROCINFO_LENGTH 14
2679#define TRACE_GRAPH_INDENT 2 2651#define TRACE_GRAPH_INDENT 2
2680 2652
2681static void print_graph_proc(int pid, const char *comm)
2682{
2683 /* sign + log10(MAX_INT) + '\0' */
2684 char pid_str[11];
2685 int spaces = 0;
2686 int len;
2687 int i;
2688
2689 sprintf(pid_str, "%d", pid);
2690
2691 /* 1 stands for the "-" character */
2692 len = strlen(comm) + strlen(pid_str) + 1;
2693
2694 if (len < TRACE_GRAPH_PROCINFO_LENGTH)
2695 spaces = TRACE_GRAPH_PROCINFO_LENGTH - len;
2696
2697 /* First spaces to align center */
2698 for (i = 0; i < spaces / 2; i++)
2699 printf(" ");
2700
2701 printf("%s-%s", comm, pid_str);
2702
2703 /* Last spaces to align center */
2704 for (i = 0; i < spaces - (spaces / 2); i++)
2705 printf(" ");
2706}
2707
2708static struct record * 2653static struct record *
2709get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func, 2654get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func,
2710 struct record *next) 2655 struct record *next)
@@ -2876,21 +2821,13 @@ static void print_graph_nested(struct event *event, void *data)
2876 2821
2877static void 2822static void
2878pretty_print_func_ent(void *data, int size, struct event *event, 2823pretty_print_func_ent(void *data, int size, struct event *event,
2879 int cpu, int pid, const char *comm, 2824 int cpu, int pid)
2880 unsigned long secs, unsigned long usecs)
2881{ 2825{
2882 struct format_field *field; 2826 struct format_field *field;
2883 struct record *rec; 2827 struct record *rec;
2884 void *copy_data; 2828 void *copy_data;
2885 unsigned long val; 2829 unsigned long val;
2886 2830
2887 printf("%5lu.%06lu | ", secs, usecs);
2888
2889 print_graph_cpu(cpu);
2890 print_graph_proc(pid, comm);
2891
2892 printf(" | ");
2893
2894 if (latency_format) { 2831 if (latency_format) {
2895 print_lat_fmt(data, size); 2832 print_lat_fmt(data, size);
2896 printf(" | "); 2833 printf(" | ");
@@ -2923,22 +2860,13 @@ out_free:
2923} 2860}
2924 2861
2925static void 2862static void
2926pretty_print_func_ret(void *data, int size __unused, struct event *event, 2863pretty_print_func_ret(void *data, int size __unused, struct event *event)
2927 int cpu, int pid, const char *comm,
2928 unsigned long secs, unsigned long usecs)
2929{ 2864{
2930 unsigned long long rettime, calltime; 2865 unsigned long long rettime, calltime;
2931 unsigned long long duration, depth; 2866 unsigned long long duration, depth;
2932 struct format_field *field; 2867 struct format_field *field;
2933 int i; 2868 int i;
2934 2869
2935 printf("%5lu.%06lu | ", secs, usecs);
2936
2937 print_graph_cpu(cpu);
2938 print_graph_proc(pid, comm);
2939
2940 printf(" | ");
2941
2942 if (latency_format) { 2870 if (latency_format) {
2943 print_lat_fmt(data, size); 2871 print_lat_fmt(data, size);
2944 printf(" | "); 2872 printf(" | ");
@@ -2976,31 +2904,21 @@ pretty_print_func_ret(void *data, int size __unused, struct event *event,
2976 2904
2977static void 2905static void
2978pretty_print_func_graph(void *data, int size, struct event *event, 2906pretty_print_func_graph(void *data, int size, struct event *event,
2979 int cpu, int pid, const char *comm, 2907 int cpu, int pid)
2980 unsigned long secs, unsigned long usecs)
2981{ 2908{
2982 if (event->flags & EVENT_FL_ISFUNCENT) 2909 if (event->flags & EVENT_FL_ISFUNCENT)
2983 pretty_print_func_ent(data, size, event, 2910 pretty_print_func_ent(data, size, event, cpu, pid);
2984 cpu, pid, comm, secs, usecs);
2985 else if (event->flags & EVENT_FL_ISFUNCRET) 2911 else if (event->flags & EVENT_FL_ISFUNCRET)
2986 pretty_print_func_ret(data, size, event, 2912 pretty_print_func_ret(data, size, event);
2987 cpu, pid, comm, secs, usecs);
2988 printf("\n"); 2913 printf("\n");
2989} 2914}
2990 2915
2991void print_event(int cpu, void *data, int size, unsigned long long nsecs, 2916void print_trace_event(int cpu, void *data, int size)
2992 char *comm)
2993{ 2917{
2994 struct event *event; 2918 struct event *event;
2995 unsigned long secs;
2996 unsigned long usecs;
2997 int type; 2919 int type;
2998 int pid; 2920 int pid;
2999 2921
3000 secs = nsecs / NSECS_PER_SEC;
3001 nsecs -= secs * NSECS_PER_SEC;
3002 usecs = nsecs / NSECS_PER_USEC;
3003
3004 type = trace_parse_common_type(data); 2922 type = trace_parse_common_type(data);
3005 2923
3006 event = trace_find_event(type); 2924 event = trace_find_event(type);
@@ -3012,17 +2930,10 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs,
3012 pid = trace_parse_common_pid(data); 2930 pid = trace_parse_common_pid(data);
3013 2931
3014 if (event->flags & (EVENT_FL_ISFUNCENT | EVENT_FL_ISFUNCRET)) 2932 if (event->flags & (EVENT_FL_ISFUNCENT | EVENT_FL_ISFUNCRET))
3015 return pretty_print_func_graph(data, size, event, cpu, 2933 return pretty_print_func_graph(data, size, event, cpu, pid);
3016 pid, comm, secs, usecs);
3017 2934
3018 if (latency_format) { 2935 if (latency_format)
3019 printf("%8.8s-%-5d %3d",
3020 comm, pid, cpu);
3021 print_lat_fmt(data, size); 2936 print_lat_fmt(data, size);
3022 } else
3023 printf("%16s-%-5d [%03d]", comm, pid, cpu);
3024
3025 printf(" %5lu.%06lu: %s: ", secs, usecs, event->name);
3026 2937
3027 if (event->flags & EVENT_FL_FAILED) { 2938 if (event->flags & EVENT_FL_FAILED) {
3028 printf("EVENT '%s' FAILED TO PARSE\n", 2939 printf("EVENT '%s' FAILED TO PARSE\n",
@@ -3031,7 +2942,6 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs,
3031 } 2942 }
3032 2943
3033 pretty_print(data, size, event); 2944 pretty_print(data, size, event);
3034 printf("\n");
3035} 2945}
3036 2946
3037static void print_fields(struct print_flag_sym *field) 2947static void print_fields(struct print_flag_sym *field)
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
index f7af2fca965d..66f4b78737ab 100644
--- a/tools/perf/util/trace-event-scripting.c
+++ b/tools/perf/util/trace-event-scripting.c
@@ -36,11 +36,10 @@ static int stop_script_unsupported(void)
36 return 0; 36 return 0;
37} 37}
38 38
39static void process_event_unsupported(int cpu __unused, 39static void process_event_unsupported(union perf_event *event __unused,
40 void *data __unused, 40 struct perf_sample *sample __unused,
41 int size __unused, 41 struct perf_session *session __unused,
42 unsigned long long nsecs __unused, 42 struct thread *thread __unused)
43 char *comm __unused)
44{ 43{
45} 44}
46 45
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index b5f12ca24d99..b04da5722437 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -3,6 +3,7 @@
3 3
4#include <stdbool.h> 4#include <stdbool.h>
5#include "parse-events.h" 5#include "parse-events.h"
6#include "session.h"
6 7
7#define __unused __attribute__((unused)) 8#define __unused __attribute__((unused))
8 9
@@ -176,8 +177,7 @@ void print_printk(void);
176 177
177int parse_ftrace_file(char *buf, unsigned long size); 178int parse_ftrace_file(char *buf, unsigned long size);
178int parse_event_file(char *buf, unsigned long size, char *sys); 179int parse_event_file(char *buf, unsigned long size, char *sys);
179void print_event(int cpu, void *data, int size, unsigned long long nsecs, 180void print_trace_event(int cpu, void *data, int size);
180 char *comm);
181 181
182extern int file_bigendian; 182extern int file_bigendian;
183extern int host_bigendian; 183extern int host_bigendian;
@@ -278,8 +278,10 @@ struct scripting_ops {
278 const char *name; 278 const char *name;
279 int (*start_script) (const char *script, int argc, const char **argv); 279 int (*start_script) (const char *script, int argc, const char **argv);
280 int (*stop_script) (void); 280 int (*stop_script) (void);
281 void (*process_event) (int cpu, void *data, int size, 281 void (*process_event) (union perf_event *event,
282 unsigned long long nsecs, char *comm); 282 struct perf_sample *sample,
283 struct perf_session *session,
284 struct thread *thread);
283 int (*generate_script) (const char *outfile); 285 int (*generate_script) (const char *outfile);
284}; 286};
285 287