diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Makefile | 8 | ||||
-rw-r--r-- | tools/perf/builtin-annotate.c | 10 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 16 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 47 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 47 | ||||
-rw-r--r-- | tools/perf/perf.c | 4 | ||||
-rw-r--r-- | tools/perf/perf.h | 4 | ||||
-rw-r--r-- | tools/perf/util/cache.h | 14 | ||||
-rw-r--r-- | tools/perf/util/color.c | 5 | ||||
-rw-r--r-- | tools/perf/util/debug.c | 6 | ||||
-rw-r--r-- | tools/perf/util/debug.h | 11 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 50 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 5 | ||||
-rw-r--r-- | tools/perf/util/include/linux/kernel.h | 9 | ||||
-rw-r--r-- | tools/perf/util/newt.c | 207 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 4 | ||||
-rw-r--r-- | tools/perf/util/session.h | 9 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 29 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 16 |
19 files changed, 419 insertions, 82 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 8a8f52db7e38..0abd25ee595f 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -513,6 +513,14 @@ else | |||
513 | LIB_OBJS += util/probe-finder.o | 513 | LIB_OBJS += util/probe-finder.o |
514 | endif | 514 | endif |
515 | 515 | ||
516 | ifneq ($(shell sh -c "(echo '\#include <newt.h>'; echo 'int main(void) { newtInit(); newtCls(); return newtFinished(); }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -lnewt -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) | ||
517 | msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev); | ||
518 | BASIC_CFLAGS += -DNO_NEWT_SUPPORT | ||
519 | else | ||
520 | EXTLIBS += -lnewt | ||
521 | LIB_OBJS += util/newt.o | ||
522 | endif | ||
523 | |||
516 | ifndef NO_LIBPERL | 524 | ifndef NO_LIBPERL |
517 | PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null` | 525 | PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null` |
518 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` | 526 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 6ad7148451c5..45d14660d53d 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -452,6 +452,16 @@ static void annotate_sym(struct hist_entry *he) | |||
452 | if (!filename) | 452 | if (!filename) |
453 | return; | 453 | return; |
454 | 454 | ||
455 | if (dso->origin == DSO__ORIG_KERNEL) { | ||
456 | if (dso->annotate_warned) | ||
457 | return; | ||
458 | dso->annotate_warned = 1; | ||
459 | pr_err("Can't annotate %s: No vmlinux file was found in the " | ||
460 | "path:\n", sym->name); | ||
461 | vmlinux_path__fprintf(stderr); | ||
462 | return; | ||
463 | } | ||
464 | |||
455 | pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__, | 465 | pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__, |
456 | filename, sym->name, map->unmap_ip(map, sym->start), | 466 | filename, sym->name, map->unmap_ip(map, sym->start), |
457 | map->unmap_ip(map, sym->end)); | 467 | map->unmap_ip(map, sym->end)); |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 3b8b6387c47c..962cdbf44ae9 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -225,7 +225,7 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n | |||
225 | return h_attr; | 225 | return h_attr; |
226 | } | 226 | } |
227 | 227 | ||
228 | static void create_counter(int counter, int cpu, pid_t pid) | 228 | static void create_counter(int counter, int cpu, pid_t pid, bool forks) |
229 | { | 229 | { |
230 | char *filter = filters[counter]; | 230 | char *filter = filters[counter]; |
231 | struct perf_event_attr *attr = attrs + counter; | 231 | struct perf_event_attr *attr = attrs + counter; |
@@ -277,6 +277,9 @@ static void create_counter(int counter, int cpu, pid_t pid) | |||
277 | attr->inherit = inherit; | 277 | attr->inherit = inherit; |
278 | attr->disabled = 1; | 278 | attr->disabled = 1; |
279 | 279 | ||
280 | if (forks) | ||
281 | attr->enable_on_exec = 1; | ||
282 | |||
280 | try_again: | 283 | try_again: |
281 | fd[nr_cpu][counter] = sys_perf_event_open(attr, pid, cpu, group_fd, 0); | 284 | fd[nr_cpu][counter] = sys_perf_event_open(attr, pid, cpu, group_fd, 0); |
282 | 285 | ||
@@ -284,7 +287,8 @@ try_again: | |||
284 | int err = errno; | 287 | int err = errno; |
285 | 288 | ||
286 | if (err == EPERM || err == EACCES) | 289 | if (err == EPERM || err == EACCES) |
287 | die("Permission error - are you root?\n"); | 290 | die("Permission error - are you root?\n" |
291 | "\t Consider tweaking /proc/sys/kernel/perf_event_paranoid.\n"); | ||
288 | else if (err == ENODEV && profile_cpu != -1) | 292 | else if (err == ENODEV && profile_cpu != -1) |
289 | die("No such device - did you specify an out-of-range profile CPU?\n"); | 293 | die("No such device - did you specify an out-of-range profile CPU?\n"); |
290 | 294 | ||
@@ -380,13 +384,13 @@ try_again: | |||
380 | ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE); | 384 | ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE); |
381 | } | 385 | } |
382 | 386 | ||
383 | static void open_counters(int cpu, pid_t pid) | 387 | static void open_counters(int cpu, pid_t pid, bool forks) |
384 | { | 388 | { |
385 | int counter; | 389 | int counter; |
386 | 390 | ||
387 | group_fd = -1; | 391 | group_fd = -1; |
388 | for (counter = 0; counter < nr_counters; counter++) | 392 | for (counter = 0; counter < nr_counters; counter++) |
389 | create_counter(counter, cpu, pid); | 393 | create_counter(counter, cpu, pid, forks); |
390 | 394 | ||
391 | nr_cpu++; | 395 | nr_cpu++; |
392 | } | 396 | } |
@@ -546,11 +550,11 @@ static int __cmd_record(int argc, const char **argv) | |||
546 | 550 | ||
547 | 551 | ||
548 | if ((!system_wide && !inherit) || profile_cpu != -1) { | 552 | if ((!system_wide && !inherit) || profile_cpu != -1) { |
549 | open_counters(profile_cpu, target_pid); | 553 | open_counters(profile_cpu, target_pid, forks); |
550 | } else { | 554 | } else { |
551 | nr_cpus = read_cpu_map(); | 555 | nr_cpus = read_cpu_map(); |
552 | for (i = 0; i < nr_cpus; i++) | 556 | for (i = 0; i < nr_cpus; i++) |
553 | open_counters(cpumap[i], target_pid); | 557 | open_counters(cpumap[i], target_pid, forks); |
554 | } | 558 | } |
555 | 559 | ||
556 | if (file_new) { | 560 | if (file_new) { |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index f815de25d0fc..1f9f8695f055 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -267,6 +267,7 @@ static int __cmd_report(void) | |||
267 | int ret = -EINVAL; | 267 | int ret = -EINVAL; |
268 | struct perf_session *session; | 268 | struct perf_session *session; |
269 | struct rb_node *next; | 269 | struct rb_node *next; |
270 | const char *help = "For a higher level overview, try: perf report --sort comm,dso"; | ||
270 | 271 | ||
271 | session = perf_session__new(input_name, O_RDONLY, force); | 272 | session = perf_session__new(input_name, O_RDONLY, force); |
272 | if (session == NULL) | 273 | if (session == NULL) |
@@ -301,30 +302,38 @@ static int __cmd_report(void) | |||
301 | stats = rb_entry(next, struct event_stat_id, rb_node); | 302 | stats = rb_entry(next, struct event_stat_id, rb_node); |
302 | perf_session__collapse_resort(&stats->hists); | 303 | perf_session__collapse_resort(&stats->hists); |
303 | perf_session__output_resort(&stats->hists, stats->stats.total); | 304 | perf_session__output_resort(&stats->hists, stats->stats.total); |
304 | if (rb_first(&session->stats_by_id) == | ||
305 | rb_last(&session->stats_by_id)) | ||
306 | fprintf(stdout, "# Samples: %Ld\n#\n", | ||
307 | stats->stats.total); | ||
308 | else | ||
309 | fprintf(stdout, "# Samples: %Ld %s\n#\n", | ||
310 | stats->stats.total, | ||
311 | __event_name(stats->type, stats->config)); | ||
312 | 305 | ||
313 | perf_session__fprintf_hists(&stats->hists, NULL, false, stdout, | 306 | if (use_browser) |
307 | perf_session__browse_hists(&stats->hists, | ||
308 | stats->stats.total, help); | ||
309 | else { | ||
310 | if (rb_first(&session->stats_by_id) == | ||
311 | rb_last(&session->stats_by_id)) | ||
312 | fprintf(stdout, "# Samples: %Ld\n#\n", | ||
313 | stats->stats.total); | ||
314 | else | ||
315 | fprintf(stdout, "# Samples: %Ld %s\n#\n", | ||
316 | stats->stats.total, | ||
317 | __event_name(stats->type, stats->config)); | ||
318 | |||
319 | perf_session__fprintf_hists(&stats->hists, NULL, false, stdout, | ||
314 | stats->stats.total); | 320 | stats->stats.total); |
315 | fprintf(stdout, "\n\n"); | 321 | fprintf(stdout, "\n\n"); |
322 | } | ||
323 | |||
316 | next = rb_next(&stats->rb_node); | 324 | next = rb_next(&stats->rb_node); |
317 | } | 325 | } |
318 | 326 | ||
319 | if (sort_order == default_sort_order && | 327 | if (!use_browser && sort_order == default_sort_order && |
320 | parent_pattern == default_parent_pattern) | 328 | parent_pattern == default_parent_pattern) { |
321 | fprintf(stdout, "#\n# (For a higher level overview, try: perf report --sort comm,dso)\n#\n"); | 329 | fprintf(stdout, "#\n# (%s)\n#\n", help); |
322 | 330 | ||
323 | if (show_threads) { | 331 | if (show_threads) { |
324 | bool raw_printing_style = !strcmp(pretty_printing_style, "raw"); | 332 | bool style = !strcmp(pretty_printing_style, "raw"); |
325 | perf_read_values_display(stdout, &show_threads_values, | 333 | perf_read_values_display(stdout, &show_threads_values, |
326 | raw_printing_style); | 334 | style); |
327 | perf_read_values_destroy(&show_threads_values); | 335 | perf_read_values_destroy(&show_threads_values); |
336 | } | ||
328 | } | 337 | } |
329 | out_delete: | 338 | out_delete: |
330 | perf_session__delete(session); | 339 | perf_session__delete(session); |
@@ -447,7 +456,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) | |||
447 | { | 456 | { |
448 | argc = parse_options(argc, argv, options, report_usage, 0); | 457 | argc = parse_options(argc, argv, options, report_usage, 0); |
449 | 458 | ||
450 | setup_pager(); | 459 | setup_browser(); |
451 | 460 | ||
452 | if (symbol__init() < 0) | 461 | if (symbol__init() < 0) |
453 | return -1; | 462 | return -1; |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1f529321607e..887ebbf5d1ff 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -133,7 +133,7 @@ static inline struct symbol *sym_entry__symbol(struct sym_entry *self) | |||
133 | return ((void *)self) + symbol_conf.priv_size; | 133 | return ((void *)self) + symbol_conf.priv_size; |
134 | } | 134 | } |
135 | 135 | ||
136 | static void get_term_dimensions(struct winsize *ws) | 136 | void get_term_dimensions(struct winsize *ws) |
137 | { | 137 | { |
138 | char *s = getenv("LINES"); | 138 | char *s = getenv("LINES"); |
139 | 139 | ||
@@ -169,7 +169,7 @@ static void sig_winch_handler(int sig __used) | |||
169 | update_print_entries(&winsize); | 169 | update_print_entries(&winsize); |
170 | } | 170 | } |
171 | 171 | ||
172 | static void parse_source(struct sym_entry *syme) | 172 | static int parse_source(struct sym_entry *syme) |
173 | { | 173 | { |
174 | struct symbol *sym; | 174 | struct symbol *sym; |
175 | struct sym_entry_source *source; | 175 | struct sym_entry_source *source; |
@@ -180,12 +180,21 @@ static void parse_source(struct sym_entry *syme) | |||
180 | u64 len; | 180 | u64 len; |
181 | 181 | ||
182 | if (!syme) | 182 | if (!syme) |
183 | return; | 183 | return -1; |
184 | |||
185 | sym = sym_entry__symbol(syme); | ||
186 | map = syme->map; | ||
187 | |||
188 | /* | ||
189 | * We can't annotate with just /proc/kallsyms | ||
190 | */ | ||
191 | if (map->dso->origin == DSO__ORIG_KERNEL) | ||
192 | return -1; | ||
184 | 193 | ||
185 | if (syme->src == NULL) { | 194 | if (syme->src == NULL) { |
186 | syme->src = zalloc(sizeof(*source)); | 195 | syme->src = zalloc(sizeof(*source)); |
187 | if (syme->src == NULL) | 196 | if (syme->src == NULL) |
188 | return; | 197 | return -1; |
189 | pthread_mutex_init(&syme->src->lock, NULL); | 198 | pthread_mutex_init(&syme->src->lock, NULL); |
190 | } | 199 | } |
191 | 200 | ||
@@ -195,9 +204,6 @@ static void parse_source(struct sym_entry *syme) | |||
195 | pthread_mutex_lock(&source->lock); | 204 | pthread_mutex_lock(&source->lock); |
196 | goto out_assign; | 205 | goto out_assign; |
197 | } | 206 | } |
198 | |||
199 | sym = sym_entry__symbol(syme); | ||
200 | map = syme->map; | ||
201 | path = map->dso->long_name; | 207 | path = map->dso->long_name; |
202 | 208 | ||
203 | len = sym->end - sym->start; | 209 | len = sym->end - sym->start; |
@@ -209,7 +215,7 @@ static void parse_source(struct sym_entry *syme) | |||
209 | 215 | ||
210 | file = popen(command, "r"); | 216 | file = popen(command, "r"); |
211 | if (!file) | 217 | if (!file) |
212 | return; | 218 | return -1; |
213 | 219 | ||
214 | pthread_mutex_lock(&source->lock); | 220 | pthread_mutex_lock(&source->lock); |
215 | source->lines_tail = &source->lines; | 221 | source->lines_tail = &source->lines; |
@@ -245,6 +251,7 @@ static void parse_source(struct sym_entry *syme) | |||
245 | out_assign: | 251 | out_assign: |
246 | sym_filter_entry = syme; | 252 | sym_filter_entry = syme; |
247 | pthread_mutex_unlock(&source->lock); | 253 | pthread_mutex_unlock(&source->lock); |
254 | return 0; | ||
248 | } | 255 | } |
249 | 256 | ||
250 | static void __zero_source_counters(struct sym_entry *syme) | 257 | static void __zero_source_counters(struct sym_entry *syme) |
@@ -411,6 +418,7 @@ static double sym_weight(const struct sym_entry *sym) | |||
411 | 418 | ||
412 | static long samples; | 419 | static long samples; |
413 | static long userspace_samples; | 420 | static long userspace_samples; |
421 | static long exact_samples; | ||
414 | static const char CONSOLE_CLEAR[] = "[H[2J"; | 422 | static const char CONSOLE_CLEAR[] = "[H[2J"; |
415 | 423 | ||
416 | static void __list_insert_active_sym(struct sym_entry *syme) | 424 | static void __list_insert_active_sym(struct sym_entry *syme) |
@@ -451,6 +459,7 @@ static void print_sym_table(void) | |||
451 | int counter, snap = !display_weighted ? sym_counter : 0; | 459 | int counter, snap = !display_weighted ? sym_counter : 0; |
452 | float samples_per_sec = samples/delay_secs; | 460 | float samples_per_sec = samples/delay_secs; |
453 | float ksamples_per_sec = (samples-userspace_samples)/delay_secs; | 461 | float ksamples_per_sec = (samples-userspace_samples)/delay_secs; |
462 | float esamples_percent = (100.0*exact_samples)/samples; | ||
454 | float sum_ksamples = 0.0; | 463 | float sum_ksamples = 0.0; |
455 | struct sym_entry *syme, *n; | 464 | struct sym_entry *syme, *n; |
456 | struct rb_root tmp = RB_ROOT; | 465 | struct rb_root tmp = RB_ROOT; |
@@ -458,7 +467,7 @@ static void print_sym_table(void) | |||
458 | int sym_width = 0, dso_width = 0, dso_short_width = 0; | 467 | int sym_width = 0, dso_width = 0, dso_short_width = 0; |
459 | const int win_width = winsize.ws_col - 1; | 468 | const int win_width = winsize.ws_col - 1; |
460 | 469 | ||
461 | samples = userspace_samples = 0; | 470 | samples = userspace_samples = exact_samples = 0; |
462 | 471 | ||
463 | /* Sort the active symbols */ | 472 | /* Sort the active symbols */ |
464 | pthread_mutex_lock(&active_symbols_lock); | 473 | pthread_mutex_lock(&active_symbols_lock); |
@@ -489,9 +498,10 @@ static void print_sym_table(void) | |||
489 | puts(CONSOLE_CLEAR); | 498 | puts(CONSOLE_CLEAR); |
490 | 499 | ||
491 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); | 500 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); |
492 | printf( " PerfTop:%8.0f irqs/sec kernel:%4.1f%% [", | 501 | printf( " PerfTop:%8.0f irqs/sec kernel:%4.1f%% exact: %4.1f%% [", |
493 | samples_per_sec, | 502 | samples_per_sec, |
494 | 100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec))); | 503 | 100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec)), |
504 | esamples_percent); | ||
495 | 505 | ||
496 | if (nr_counters == 1 || !display_weighted) { | 506 | if (nr_counters == 1 || !display_weighted) { |
497 | printf("%Ld", (u64)attrs[0].sample_period); | 507 | printf("%Ld", (u64)attrs[0].sample_period); |
@@ -960,6 +970,9 @@ static void event__process_sample(const event_t *self, | |||
960 | return; | 970 | return; |
961 | } | 971 | } |
962 | 972 | ||
973 | if (self->header.misc & PERF_RECORD_MISC_EXACT) | ||
974 | exact_samples++; | ||
975 | |||
963 | if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 || | 976 | if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 || |
964 | al.filtered) | 977 | al.filtered) |
965 | return; | 978 | return; |
@@ -990,7 +1003,17 @@ static void event__process_sample(const event_t *self, | |||
990 | if (sym_filter_entry_sched) { | 1003 | if (sym_filter_entry_sched) { |
991 | sym_filter_entry = sym_filter_entry_sched; | 1004 | sym_filter_entry = sym_filter_entry_sched; |
992 | sym_filter_entry_sched = NULL; | 1005 | sym_filter_entry_sched = NULL; |
993 | parse_source(sym_filter_entry); | 1006 | if (parse_source(sym_filter_entry) < 0) { |
1007 | struct symbol *sym = sym_entry__symbol(sym_filter_entry); | ||
1008 | |||
1009 | pr_err("Can't annotate %s", sym->name); | ||
1010 | if (sym_filter_entry->map->dso->origin == DSO__ORIG_KERNEL) { | ||
1011 | pr_err(": No vmlinux file was found in the path:\n"); | ||
1012 | vmlinux_path__fprintf(stderr); | ||
1013 | } else | ||
1014 | pr_err(".\n"); | ||
1015 | exit(1); | ||
1016 | } | ||
994 | } | 1017 | } |
995 | 1018 | ||
996 | syme = symbol__priv(al.sym); | 1019 | syme = symbol__priv(al.sym); |
diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 57cb107c1f13..0d4b9edfab12 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include "util/string.h" | 16 | #include "util/string.h" |
17 | #include "util/debugfs.h" | 17 | #include "util/debugfs.h" |
18 | 18 | ||
19 | bool use_browser; | ||
20 | |||
19 | const char perf_usage_string[] = | 21 | const char perf_usage_string[] = |
20 | "perf [--version] [--help] COMMAND [ARGS]"; | 22 | "perf [--version] [--help] COMMAND [ARGS]"; |
21 | 23 | ||
@@ -265,6 +267,8 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) | |||
265 | if (status) | 267 | if (status) |
266 | return status & 0xff; | 268 | return status & 0xff; |
267 | 269 | ||
270 | exit_browser(); | ||
271 | |||
268 | /* Somebody closed stdout? */ | 272 | /* Somebody closed stdout? */ |
269 | if (fstat(fileno(stdout), &st)) | 273 | if (fstat(fileno(stdout), &st)) |
270 | return 0; | 274 | return 0; |
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 6fb379bc1d1f..aa786158b668 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -1,6 +1,10 @@ | |||
1 | #ifndef _PERF_PERF_H | 1 | #ifndef _PERF_PERF_H |
2 | #define _PERF_PERF_H | 2 | #define _PERF_PERF_H |
3 | 3 | ||
4 | struct winsize; | ||
5 | |||
6 | void get_term_dimensions(struct winsize *ws); | ||
7 | |||
4 | #if defined(__i386__) | 8 | #if defined(__i386__) |
5 | #include "../../arch/x86/include/asm/unistd.h" | 9 | #include "../../arch/x86/include/asm/unistd.h" |
6 | #define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") | 10 | #define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") |
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 918eb376abe3..47b12a3d11bf 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __PERF_CACHE_H | 1 | #ifndef __PERF_CACHE_H |
2 | #define __PERF_CACHE_H | 2 | #define __PERF_CACHE_H |
3 | 3 | ||
4 | #include <stdbool.h> | ||
4 | #include "util.h" | 5 | #include "util.h" |
5 | #include "strbuf.h" | 6 | #include "strbuf.h" |
6 | #include "../perf.h" | 7 | #include "../perf.h" |
@@ -69,6 +70,19 @@ extern const char *pager_program; | |||
69 | extern int pager_in_use(void); | 70 | extern int pager_in_use(void); |
70 | extern int pager_use_color; | 71 | extern int pager_use_color; |
71 | 72 | ||
73 | extern bool use_browser; | ||
74 | |||
75 | #ifdef NO_NEWT_SUPPORT | ||
76 | static inline void setup_browser(void) | ||
77 | { | ||
78 | setup_pager(); | ||
79 | } | ||
80 | static inline void exit_browser(void) {} | ||
81 | #else | ||
82 | void setup_browser(void); | ||
83 | void exit_browser(void); | ||
84 | #endif | ||
85 | |||
72 | extern const char *editor_program; | 86 | extern const char *editor_program; |
73 | extern const char *excludes_file; | 87 | extern const char *excludes_file; |
74 | 88 | ||
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index e88bca55a599..9da01914e0af 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c | |||
@@ -203,7 +203,10 @@ int color_fprintf(FILE *fp, const char *color, const char *fmt, ...) | |||
203 | int r; | 203 | int r; |
204 | 204 | ||
205 | va_start(args, fmt); | 205 | va_start(args, fmt); |
206 | r = color_vfprintf(fp, color, fmt, args); | 206 | if (use_browser) |
207 | r = vfprintf(fp, fmt, args); | ||
208 | else | ||
209 | r = color_vfprintf(fp, color, fmt, args); | ||
207 | va_end(args); | 210 | va_end(args); |
208 | return r; | 211 | return r; |
209 | } | 212 | } |
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 0905600c3851..033d66db863a 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <stdarg.h> | 6 | #include <stdarg.h> |
7 | #include <stdio.h> | 7 | #include <stdio.h> |
8 | 8 | ||
9 | #include "cache.h" | ||
9 | #include "color.h" | 10 | #include "color.h" |
10 | #include "event.h" | 11 | #include "event.h" |
11 | #include "debug.h" | 12 | #include "debug.h" |
@@ -21,7 +22,10 @@ int eprintf(int level, const char *fmt, ...) | |||
21 | 22 | ||
22 | if (verbose >= level) { | 23 | if (verbose >= level) { |
23 | va_start(args, fmt); | 24 | va_start(args, fmt); |
24 | ret = vfprintf(stderr, fmt, args); | 25 | if (use_browser) |
26 | ret = browser__show_help(fmt, args); | ||
27 | else | ||
28 | ret = vfprintf(stderr, fmt, args); | ||
25 | va_end(args); | 29 | va_end(args); |
26 | } | 30 | } |
27 | 31 | ||
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index c6c24c522dea..0172edf3f153 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h | |||
@@ -7,9 +7,16 @@ | |||
7 | extern int verbose; | 7 | extern int verbose; |
8 | extern int dump_trace; | 8 | extern int dump_trace; |
9 | 9 | ||
10 | int eprintf(int level, | ||
11 | const char *fmt, ...) __attribute__((format(printf, 2, 3))); | ||
12 | int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); | 10 | int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); |
13 | void trace_event(event_t *event); | 11 | void trace_event(event_t *event); |
14 | 12 | ||
13 | #ifdef NO_NEWT_SUPPORT | ||
14 | static inline int browser__show_help(const char *format __used, va_list ap __used) | ||
15 | { | ||
16 | return 0; | ||
17 | } | ||
18 | #else | ||
19 | int browser__show_help(const char *format, va_list ap); | ||
20 | #endif | ||
21 | |||
15 | #endif /* __PERF_DEBUG_H */ | 22 | #endif /* __PERF_DEBUG_H */ |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index bdcfd6190b21..1a4e8376d843 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -455,11 +455,11 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
455 | return ret; | 455 | return ret; |
456 | } | 456 | } |
457 | 457 | ||
458 | static size_t hist_entry__fprintf(struct hist_entry *self, | 458 | size_t hist_entry__fprintf(struct hist_entry *self, |
459 | struct perf_session *pair_session, | 459 | struct perf_session *pair_session, |
460 | bool show_displacement, | 460 | bool show_displacement, |
461 | long displacement, FILE *fp, | 461 | long displacement, FILE *fp, |
462 | u64 session_total) | 462 | u64 session_total) |
463 | { | 463 | { |
464 | struct sort_entry *se; | 464 | struct sort_entry *se; |
465 | u64 count, total; | 465 | u64 count, total; |
@@ -485,9 +485,9 @@ static size_t hist_entry__fprintf(struct hist_entry *self, | |||
485 | 485 | ||
486 | if (symbol_conf.show_nr_samples) { | 486 | if (symbol_conf.show_nr_samples) { |
487 | if (sep) | 487 | if (sep) |
488 | fprintf(fp, "%c%lld", *sep, count); | 488 | ret += fprintf(fp, "%c%lld", *sep, count); |
489 | else | 489 | else |
490 | fprintf(fp, "%11lld", count); | 490 | ret += fprintf(fp, "%11lld", count); |
491 | } | 491 | } |
492 | 492 | ||
493 | if (pair_session) { | 493 | if (pair_session) { |
@@ -518,9 +518,9 @@ static size_t hist_entry__fprintf(struct hist_entry *self, | |||
518 | snprintf(bf, sizeof(bf), " "); | 518 | snprintf(bf, sizeof(bf), " "); |
519 | 519 | ||
520 | if (sep) | 520 | if (sep) |
521 | fprintf(fp, "%c%s", *sep, bf); | 521 | ret += fprintf(fp, "%c%s", *sep, bf); |
522 | else | 522 | else |
523 | fprintf(fp, "%6.6s", bf); | 523 | ret += fprintf(fp, "%6.6s", bf); |
524 | } | 524 | } |
525 | } | 525 | } |
526 | 526 | ||
@@ -528,27 +528,27 @@ static size_t hist_entry__fprintf(struct hist_entry *self, | |||
528 | if (se->elide) | 528 | if (se->elide) |
529 | continue; | 529 | continue; |
530 | 530 | ||
531 | fprintf(fp, "%s", sep ?: " "); | 531 | ret += fprintf(fp, "%s", sep ?: " "); |
532 | ret += se->print(fp, self, se->width ? *se->width : 0); | 532 | ret += se->print(fp, self, se->width ? *se->width : 0); |
533 | } | 533 | } |
534 | 534 | ||
535 | ret += fprintf(fp, "\n"); | 535 | return ret + fprintf(fp, "\n"); |
536 | 536 | } | |
537 | if (symbol_conf.use_callchain) { | ||
538 | int left_margin = 0; | ||
539 | 537 | ||
540 | if (sort__first_dimension == SORT_COMM) { | 538 | static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, |
541 | se = list_first_entry(&hist_entry__sort_list, typeof(*se), | 539 | u64 session_total) |
542 | list); | 540 | { |
543 | left_margin = se->width ? *se->width : 0; | 541 | int left_margin = 0; |
544 | left_margin -= thread__comm_len(self->thread); | ||
545 | } | ||
546 | 542 | ||
547 | hist_entry_callchain__fprintf(fp, self, session_total, | 543 | if (sort__first_dimension == SORT_COMM) { |
548 | left_margin); | 544 | struct sort_entry *se = list_first_entry(&hist_entry__sort_list, |
545 | typeof(*se), list); | ||
546 | left_margin = se->width ? *se->width : 0; | ||
547 | left_margin -= thread__comm_len(self->thread); | ||
549 | } | 548 | } |
550 | 549 | ||
551 | return ret; | 550 | return hist_entry_callchain__fprintf(fp, self, session_total, |
551 | left_margin); | ||
552 | } | 552 | } |
553 | 553 | ||
554 | size_t perf_session__fprintf_hists(struct rb_root *hists, | 554 | size_t perf_session__fprintf_hists(struct rb_root *hists, |
@@ -655,6 +655,10 @@ print_entries: | |||
655 | } | 655 | } |
656 | ret += hist_entry__fprintf(h, pair, show_displacement, | 656 | ret += hist_entry__fprintf(h, pair, show_displacement, |
657 | displacement, fp, session_total); | 657 | displacement, fp, session_total); |
658 | |||
659 | if (symbol_conf.use_callchain) | ||
660 | ret += hist_entry__fprintf_callchain(h, fp, session_total); | ||
661 | |||
658 | if (h->map == NULL && verbose > 1) { | 662 | if (h->map == NULL && verbose > 1) { |
659 | __map_groups__fprintf_maps(&h->thread->mg, | 663 | __map_groups__fprintf_maps(&h->thread->mg, |
660 | MAP__FUNCTION, fp); | 664 | MAP__FUNCTION, fp); |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 16f360cce5bf..fe366ce5db45 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -18,6 +18,11 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | |||
18 | u64 count, bool *hit); | 18 | u64 count, bool *hit); |
19 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); | 19 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); |
20 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); | 20 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); |
21 | size_t hist_entry__fprintf(struct hist_entry *self, | ||
22 | struct perf_session *pair_session, | ||
23 | bool show_displacement, | ||
24 | long displacement, FILE *fp, | ||
25 | u64 session_total); | ||
21 | void hist_entry__free(struct hist_entry *); | 26 | void hist_entry__free(struct hist_entry *); |
22 | 27 | ||
23 | void perf_session__output_resort(struct rb_root *hists, u64 total_samples); | 28 | void perf_session__output_resort(struct rb_root *hists, u64 total_samples); |
diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h index f2611655ab51..388ab1bfd114 100644 --- a/tools/perf/util/include/linux/kernel.h +++ b/tools/perf/util/include/linux/kernel.h | |||
@@ -85,16 +85,19 @@ simple_strtoul(const char *nptr, char **endptr, int base) | |||
85 | return strtoul(nptr, endptr, base); | 85 | return strtoul(nptr, endptr, base); |
86 | } | 86 | } |
87 | 87 | ||
88 | int eprintf(int level, | ||
89 | const char *fmt, ...) __attribute__((format(printf, 2, 3))); | ||
90 | |||
88 | #ifndef pr_fmt | 91 | #ifndef pr_fmt |
89 | #define pr_fmt(fmt) fmt | 92 | #define pr_fmt(fmt) fmt |
90 | #endif | 93 | #endif |
91 | 94 | ||
92 | #define pr_err(fmt, ...) \ | 95 | #define pr_err(fmt, ...) \ |
93 | do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0) | 96 | eprintf(0, pr_fmt(fmt), ##__VA_ARGS__) |
94 | #define pr_warning(fmt, ...) \ | 97 | #define pr_warning(fmt, ...) \ |
95 | do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0) | 98 | eprintf(0, pr_fmt(fmt), ##__VA_ARGS__) |
96 | #define pr_info(fmt, ...) \ | 99 | #define pr_info(fmt, ...) \ |
97 | do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0) | 100 | eprintf(0, pr_fmt(fmt), ##__VA_ARGS__) |
98 | #define pr_debug(fmt, ...) \ | 101 | #define pr_debug(fmt, ...) \ |
99 | eprintf(1, pr_fmt(fmt), ##__VA_ARGS__) | 102 | eprintf(1, pr_fmt(fmt), ##__VA_ARGS__) |
100 | #define pr_debugN(n, fmt, ...) \ | 103 | #define pr_debugN(n, fmt, ...) \ |
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c new file mode 100644 index 000000000000..2d19e7a3e6e8 --- /dev/null +++ b/tools/perf/util/newt.c | |||
@@ -0,0 +1,207 @@ | |||
1 | #define _GNU_SOURCE | ||
2 | #include <stdio.h> | ||
3 | #undef _GNU_SOURCE | ||
4 | |||
5 | #include <stdlib.h> | ||
6 | #include <newt.h> | ||
7 | #include <sys/ttydefaults.h> | ||
8 | |||
9 | #include "cache.h" | ||
10 | #include "hist.h" | ||
11 | #include "session.h" | ||
12 | #include "sort.h" | ||
13 | #include "symbol.h" | ||
14 | |||
15 | static void newt_form__set_exit_keys(newtComponent self) | ||
16 | { | ||
17 | newtFormAddHotKey(self, NEWT_KEY_ESCAPE); | ||
18 | newtFormAddHotKey(self, 'Q'); | ||
19 | newtFormAddHotKey(self, 'q'); | ||
20 | newtFormAddHotKey(self, CTRL('c')); | ||
21 | } | ||
22 | |||
23 | static newtComponent newt_form__new(void) | ||
24 | { | ||
25 | newtComponent self = newtForm(NULL, NULL, 0); | ||
26 | if (self) | ||
27 | newt_form__set_exit_keys(self); | ||
28 | return self; | ||
29 | } | ||
30 | |||
31 | static size_t hist_entry__append_browser(struct hist_entry *self, | ||
32 | newtComponent listbox, u64 total) | ||
33 | { | ||
34 | char bf[1024]; | ||
35 | size_t len; | ||
36 | FILE *fp; | ||
37 | |||
38 | if (symbol_conf.exclude_other && !self->parent) | ||
39 | return 0; | ||
40 | |||
41 | fp = fmemopen(bf, sizeof(bf), "w"); | ||
42 | if (fp == NULL) | ||
43 | return 0; | ||
44 | |||
45 | len = hist_entry__fprintf(self, NULL, false, 0, fp, total); | ||
46 | |||
47 | fclose(fp); | ||
48 | newtListboxAppendEntry(listbox, bf, self); | ||
49 | return len; | ||
50 | } | ||
51 | |||
52 | static void hist_entry__annotate_browser(struct hist_entry *self) | ||
53 | { | ||
54 | FILE *fp; | ||
55 | int cols, rows; | ||
56 | newtComponent form, listbox; | ||
57 | struct newtExitStruct es; | ||
58 | char *str; | ||
59 | size_t line_len, max_line_len = 0; | ||
60 | size_t max_usable_width; | ||
61 | char *line = NULL; | ||
62 | |||
63 | if (self->sym == NULL) | ||
64 | return; | ||
65 | |||
66 | if (asprintf(&str, "perf annotate %s 2>&1 | expand", self->sym->name) < 0) | ||
67 | return; | ||
68 | |||
69 | fp = popen(str, "r"); | ||
70 | if (fp == NULL) | ||
71 | goto out_free_str; | ||
72 | |||
73 | newtPushHelpLine("Press ESC to exit"); | ||
74 | newtGetScreenSize(&cols, &rows); | ||
75 | listbox = newtListbox(0, 0, rows - 5, NEWT_FLAG_SCROLL); | ||
76 | |||
77 | while (!feof(fp)) { | ||
78 | if (getline(&line, &line_len, fp) < 0 || !line_len) | ||
79 | break; | ||
80 | while (line_len != 0 && isspace(line[line_len - 1])) | ||
81 | line[--line_len] = '\0'; | ||
82 | |||
83 | if (line_len > max_line_len) | ||
84 | max_line_len = line_len; | ||
85 | newtListboxAppendEntry(listbox, line, NULL); | ||
86 | } | ||
87 | fclose(fp); | ||
88 | free(line); | ||
89 | |||
90 | max_usable_width = cols - 22; | ||
91 | if (max_line_len > max_usable_width) | ||
92 | max_line_len = max_usable_width; | ||
93 | |||
94 | newtListboxSetWidth(listbox, max_line_len); | ||
95 | |||
96 | newtCenteredWindow(max_line_len + 2, rows - 5, self->sym->name); | ||
97 | form = newt_form__new(); | ||
98 | newtFormAddComponents(form, listbox, NULL); | ||
99 | |||
100 | newtFormRun(form, &es); | ||
101 | newtFormDestroy(form); | ||
102 | newtPopWindow(); | ||
103 | newtPopHelpLine(); | ||
104 | out_free_str: | ||
105 | free(str); | ||
106 | } | ||
107 | |||
108 | void perf_session__browse_hists(struct rb_root *hists, u64 session_total, | ||
109 | const char *helpline) | ||
110 | { | ||
111 | struct sort_entry *se; | ||
112 | struct rb_node *nd; | ||
113 | unsigned int width; | ||
114 | char *col_width = symbol_conf.col_width_list_str; | ||
115 | int rows; | ||
116 | size_t max_len = 0; | ||
117 | char str[1024]; | ||
118 | newtComponent form, listbox; | ||
119 | struct newtExitStruct es; | ||
120 | |||
121 | snprintf(str, sizeof(str), "Samples: %Ld", session_total); | ||
122 | newtDrawRootText(0, 0, str); | ||
123 | newtPushHelpLine(helpline); | ||
124 | |||
125 | newtGetScreenSize(NULL, &rows); | ||
126 | |||
127 | form = newt_form__new(); | ||
128 | |||
129 | listbox = newtListbox(1, 1, rows - 2, (NEWT_FLAG_SCROLL | | ||
130 | NEWT_FLAG_BORDER | | ||
131 | NEWT_FLAG_RETURNEXIT)); | ||
132 | |||
133 | list_for_each_entry(se, &hist_entry__sort_list, list) { | ||
134 | if (se->elide) | ||
135 | continue; | ||
136 | width = strlen(se->header); | ||
137 | if (se->width) { | ||
138 | if (symbol_conf.col_width_list_str) { | ||
139 | if (col_width) { | ||
140 | *se->width = atoi(col_width); | ||
141 | col_width = strchr(col_width, ','); | ||
142 | if (col_width) | ||
143 | ++col_width; | ||
144 | } | ||
145 | } | ||
146 | *se->width = max(*se->width, width); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | for (nd = rb_first(hists); nd; nd = rb_next(nd)) { | ||
151 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | ||
152 | size_t len = hist_entry__append_browser(h, listbox, session_total); | ||
153 | if (len > max_len) | ||
154 | max_len = len; | ||
155 | } | ||
156 | |||
157 | newtListboxSetWidth(listbox, max_len); | ||
158 | newtFormAddComponents(form, listbox, NULL); | ||
159 | |||
160 | while (1) { | ||
161 | struct hist_entry *selection; | ||
162 | |||
163 | newtFormRun(form, &es); | ||
164 | if (es.reason == NEWT_EXIT_HOTKEY) | ||
165 | break; | ||
166 | selection = newtListboxGetCurrent(listbox); | ||
167 | hist_entry__annotate_browser(selection); | ||
168 | } | ||
169 | |||
170 | newtFormDestroy(form); | ||
171 | } | ||
172 | |||
173 | int browser__show_help(const char *format, va_list ap) | ||
174 | { | ||
175 | int ret; | ||
176 | static int backlog; | ||
177 | static char msg[1024]; | ||
178 | |||
179 | ret = vsnprintf(msg + backlog, sizeof(msg) - backlog, format, ap); | ||
180 | backlog += ret; | ||
181 | |||
182 | if (msg[backlog - 1] == '\n') { | ||
183 | newtPopHelpLine(); | ||
184 | newtPushHelpLine(msg); | ||
185 | newtRefresh(); | ||
186 | backlog = 0; | ||
187 | } | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | void setup_browser(void) | ||
193 | { | ||
194 | if (!isatty(1)) | ||
195 | return; | ||
196 | |||
197 | use_browser = true; | ||
198 | newtInit(); | ||
199 | newtCls(); | ||
200 | newtPushHelpLine(" "); | ||
201 | } | ||
202 | |||
203 | void exit_browser(void) | ||
204 | { | ||
205 | if (use_browser) | ||
206 | newtFinished(); | ||
207 | } | ||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 05d0c5c2030c..a2014459125a 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -656,6 +656,10 @@ parse_raw_event(const char **strp, struct perf_event_attr *attr) | |||
656 | return EVT_FAILED; | 656 | return EVT_FAILED; |
657 | n = hex2u64(str + 1, &config); | 657 | n = hex2u64(str + 1, &config); |
658 | if (n > 0) { | 658 | if (n > 0) { |
659 | if (str[n+1] == 'p') { | ||
660 | attr->precise = 1; | ||
661 | n++; | ||
662 | } | ||
659 | *strp = str + n + 1; | 663 | *strp = str + n + 1; |
660 | attr->type = PERF_TYPE_RAW; | 664 | attr->type = PERF_TYPE_RAW; |
661 | attr->config = config; | 665 | attr->config = config; |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 5c33417eebb3..34d73395baac 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -86,4 +86,13 @@ static inline struct map * | |||
86 | { | 86 | { |
87 | return map_groups__new_module(&self->kmaps, start, filename); | 87 | return map_groups__new_module(&self->kmaps, start, filename); |
88 | } | 88 | } |
89 | |||
90 | #ifdef NO_NEWT_SUPPORT | ||
91 | static inline void perf_session__browse_hists(struct rb_root *hists __used, | ||
92 | u64 session_total __used, | ||
93 | const char *helpline __used) {} | ||
94 | #else | ||
95 | void perf_session__browse_hists(struct rb_root *hists, u64 session_total, | ||
96 | const char *helpline); | ||
97 | #endif | ||
89 | #endif /* __PERF_SESSION_H */ | 98 | #endif /* __PERF_SESSION_H */ |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index c458c4a371d1..3eb9de4baef3 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -18,18 +18,6 @@ | |||
18 | #define NT_GNU_BUILD_ID 3 | 18 | #define NT_GNU_BUILD_ID 3 |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | enum dso_origin { | ||
22 | DSO__ORIG_KERNEL = 0, | ||
23 | DSO__ORIG_JAVA_JIT, | ||
24 | DSO__ORIG_BUILD_ID_CACHE, | ||
25 | DSO__ORIG_FEDORA, | ||
26 | DSO__ORIG_UBUNTU, | ||
27 | DSO__ORIG_BUILDID, | ||
28 | DSO__ORIG_DSO, | ||
29 | DSO__ORIG_KMODULE, | ||
30 | DSO__ORIG_NOT_FOUND, | ||
31 | }; | ||
32 | |||
33 | static void dsos__add(struct list_head *head, struct dso *dso); | 21 | static void dsos__add(struct list_head *head, struct dso *dso); |
34 | static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); | 22 | static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); |
35 | static int dso__load_kernel_sym(struct dso *self, struct map *map, | 23 | static int dso__load_kernel_sym(struct dso *self, struct map *map, |
@@ -870,8 +858,8 @@ out_close: | |||
870 | if (err == 0) | 858 | if (err == 0) |
871 | return nr; | 859 | return nr; |
872 | out: | 860 | out: |
873 | pr_warning("%s: problems reading %s PLT info.\n", | 861 | pr_debug("%s: problems reading %s PLT info.\n", |
874 | __func__, self->long_name); | 862 | __func__, self->long_name); |
875 | return 0; | 863 | return 0; |
876 | } | 864 | } |
877 | 865 | ||
@@ -1025,7 +1013,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
1025 | } | 1013 | } |
1026 | curr_map->map_ip = identity__map_ip; | 1014 | curr_map->map_ip = identity__map_ip; |
1027 | curr_map->unmap_ip = identity__map_ip; | 1015 | curr_map->unmap_ip = identity__map_ip; |
1028 | curr_dso->origin = DSO__ORIG_KERNEL; | 1016 | curr_dso->origin = self->origin; |
1029 | map_groups__insert(kmap->kmaps, curr_map); | 1017 | map_groups__insert(kmap->kmaps, curr_map); |
1030 | dsos__add(&dsos__kernel, curr_dso); | 1018 | dsos__add(&dsos__kernel, curr_dso); |
1031 | dso__set_loaded(curr_dso, map->type); | 1019 | dso__set_loaded(curr_dso, map->type); |
@@ -1895,6 +1883,17 @@ out_fail: | |||
1895 | return -1; | 1883 | return -1; |
1896 | } | 1884 | } |
1897 | 1885 | ||
1886 | size_t vmlinux_path__fprintf(FILE *fp) | ||
1887 | { | ||
1888 | int i; | ||
1889 | size_t printed = 0; | ||
1890 | |||
1891 | for (i = 0; i < vmlinux_path__nr_entries; ++i) | ||
1892 | printed += fprintf(fp, "[%d] %s\n", i, vmlinux_path[i]); | ||
1893 | |||
1894 | return printed; | ||
1895 | } | ||
1896 | |||
1898 | static int setup_list(struct strlist **list, const char *list_str, | 1897 | static int setup_list(struct strlist **list, const char *list_str, |
1899 | const char *list_name) | 1898 | const char *list_name) |
1900 | { | 1899 | { |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index f30a37428919..0da2455d5b90 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -106,6 +106,7 @@ struct dso { | |||
106 | u8 has_build_id:1; | 106 | u8 has_build_id:1; |
107 | u8 kernel:1; | 107 | u8 kernel:1; |
108 | u8 hit:1; | 108 | u8 hit:1; |
109 | u8 annotate_warned:1; | ||
109 | unsigned char origin; | 110 | unsigned char origin; |
110 | u8 sorted_by_name; | 111 | u8 sorted_by_name; |
111 | u8 loaded; | 112 | u8 loaded; |
@@ -150,6 +151,19 @@ size_t dsos__fprintf_buildid(FILE *fp, bool with_hits); | |||
150 | 151 | ||
151 | size_t dso__fprintf_buildid(struct dso *self, FILE *fp); | 152 | size_t dso__fprintf_buildid(struct dso *self, FILE *fp); |
152 | size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); | 153 | size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); |
154 | |||
155 | enum dso_origin { | ||
156 | DSO__ORIG_KERNEL = 0, | ||
157 | DSO__ORIG_JAVA_JIT, | ||
158 | DSO__ORIG_BUILD_ID_CACHE, | ||
159 | DSO__ORIG_FEDORA, | ||
160 | DSO__ORIG_UBUNTU, | ||
161 | DSO__ORIG_BUILDID, | ||
162 | DSO__ORIG_DSO, | ||
163 | DSO__ORIG_KMODULE, | ||
164 | DSO__ORIG_NOT_FOUND, | ||
165 | }; | ||
166 | |||
153 | char dso__symtab_origin(const struct dso *self); | 167 | char dso__symtab_origin(const struct dso *self); |
154 | void dso__set_long_name(struct dso *self, char *name); | 168 | void dso__set_long_name(struct dso *self, char *name); |
155 | void dso__set_build_id(struct dso *self, void *build_id); | 169 | void dso__set_build_id(struct dso *self, void *build_id); |
@@ -169,4 +183,6 @@ int kallsyms__parse(const char *filename, void *arg, | |||
169 | int symbol__init(void); | 183 | int symbol__init(void); |
170 | bool symbol_type__is_a(char symbol_type, enum map_type map_type); | 184 | bool symbol_type__is_a(char symbol_type, enum map_type map_type); |
171 | 185 | ||
186 | size_t vmlinux_path__fprintf(FILE *fp); | ||
187 | |||
172 | #endif /* __PERF_SYMBOL */ | 188 | #endif /* __PERF_SYMBOL */ |