diff options
Diffstat (limited to 'tools')
39 files changed, 384 insertions, 198 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 158c30e8210c..207dee5c5b16 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -165,8 +165,12 @@ grep-libs = $(filter -l%,$(1)) strip-libs = $(filter-out -l%,$(1)) $(OUTPUT)python/perf.so: $(PYRF_OBJS) - $(QUIET_GEN)python util/setup.py --quiet build_ext --build-lib='$(OUTPUT)python' \ - --build-temp='$(OUTPUT)python/temp' + $(QUIET_GEN)( \ + export CFLAGS="$(BASIC_CFLAGS)"; \ + python util/setup.py --quiet build_ext --build-lib='$(OUTPUT)python' \ + --build-temp='$(OUTPUT)python/temp' \ + ) + # # No Perl scripts right now: # diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 695de4b5ae63..e18eb7ed30ae 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -42,9 +42,9 @@ static const char *sym_hist_filter; static int perf_evlist__add_sample(struct perf_evlist *evlist, struct perf_sample *sample, + struct perf_evsel *evsel, struct addr_location *al) { - struct perf_evsel *evsel; struct hist_entry *he; int ret; @@ -59,18 +59,6 @@ static int perf_evlist__add_sample(struct perf_evlist *evlist, return 0; } - evsel = perf_evlist__id2evsel(evlist, sample->id); - if (evsel == NULL) { - /* - * FIXME: Propagate this back, but at least we're in a builtin, - * where exit() is allowed. ;-) - */ - ui__warning("Invalid %s file, contains samples with id not in " - "its header!\n", input_name); - exit_browser(0); - exit(1); - } - he = __hists__add_entry(&evsel->hists, al, NULL, 1); if (he == NULL) return -ENOMEM; @@ -92,6 +80,7 @@ static int perf_evlist__add_sample(struct perf_evlist *evlist, static int process_sample_event(union perf_event *event, struct perf_sample *sample, + struct perf_evsel *evsel, struct perf_session *session) { struct addr_location al; @@ -103,7 +92,8 @@ static int process_sample_event(union perf_event *event, return -1; } - if (!al.filtered && perf_evlist__add_sample(session->evlist, sample, &al)) { + if (!al.filtered && + perf_evlist__add_sample(session->evlist, sample, evsel, &al)) { pr_warning("problem incrementing symbol count, " "skipping event\n"); return -1; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 6b7d91160ecb..e8219990f8b8 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -32,6 +32,7 @@ static int hists__add_entry(struct hists *self, static int diff__process_sample_event(union perf_event *event, struct perf_sample *sample, + struct perf_evsel *evsel __used, struct perf_session *session) { struct addr_location al; diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index e29f04ed3396..8dfc12bb119b 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -43,6 +43,14 @@ static int perf_event__repipe(union perf_event *event, return perf_event__repipe_synth(event, session); } +static int perf_event__repipe_sample(union perf_event *event, + struct perf_sample *sample __used, + struct perf_evsel *evsel __used, + struct perf_session *session) +{ + return perf_event__repipe_synth(event, session); +} + static int perf_event__repipe_mmap(union perf_event *event, struct perf_sample *sample, struct perf_session *session) @@ -124,6 +132,7 @@ static int dso__inject_build_id(struct dso *self, struct perf_session *session) static int perf_event__inject_buildid(union perf_event *event, struct perf_sample *sample, + struct perf_evsel *evsel __used, struct perf_session *session) { struct addr_location al; @@ -164,7 +173,7 @@ repipe: } struct perf_event_ops inject_ops = { - .sample = perf_event__repipe, + .sample = perf_event__repipe_sample, .mmap = perf_event__repipe, .comm = perf_event__repipe, .fork = perf_event__repipe, diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 7f618f4e7b79..225e963df105 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -305,6 +305,7 @@ static void process_raw_event(union perf_event *raw_event __used, void *data, static int process_sample_event(union perf_event *event, struct perf_sample *sample, + struct perf_evsel *evsel __used, struct perf_session *session) { struct thread *thread = perf_session__findnew(session, event->ip.pid); diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 7a2a79d2cf2c..9ac05aafd9b2 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -845,7 +845,9 @@ static void dump_info(void) die("Unknown type of information\n"); } -static int process_sample_event(union perf_event *event, struct perf_sample *sample, +static int process_sample_event(union perf_event *event, + struct perf_sample *sample, + struct perf_evsel *evsel __used, struct perf_session *s) { struct thread *thread = perf_session__findnew(s, sample->tid); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 6febcc168a8c..416538248a4b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -41,7 +41,7 @@ static u64 user_interval = ULLONG_MAX; static u64 default_interval = 0; static unsigned int page_size; -static unsigned int mmap_pages = 128; +static unsigned int mmap_pages = UINT_MAX; static unsigned int user_freq = UINT_MAX; static int freq = 1000; static int output; @@ -163,6 +163,7 @@ static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist) struct perf_event_attr *attr = &evsel->attr; int track = !evsel->idx; /* only the first counter needs these */ + attr->inherit = !no_inherit; attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING | PERF_FORMAT_ID; @@ -251,6 +252,9 @@ static void open_counters(struct perf_evlist *evlist) { struct perf_evsel *pos; + if (evlist->cpus->map[0] < 0) + no_inherit = true; + list_for_each_entry(pos, &evlist->entries, node) { struct perf_event_attr *attr = &pos->attr; /* @@ -271,15 +275,13 @@ static void open_counters(struct perf_evlist *evlist) retry_sample_id: attr->sample_id_all = sample_id_all_avail ? 1 : 0; try_again: - if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group, - !no_inherit) < 0) { + if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group) < 0) { int err = errno; - if (err == EPERM || err == EACCES) - die("Permission error - are you root?\n" - "\t Consider tweaking" - " /proc/sys/kernel/perf_event_paranoid.\n"); - else if (err == ENODEV && cpu_list) { + if (err == EPERM || err == EACCES) { + ui__warning_paranoid(); + exit(EXIT_FAILURE); + } else if (err == ENODEV && cpu_list) { die("No such device - did you specify" " an out-of-range profile CPU?\n"); } else if (err == EINVAL && sample_id_all_avail) { @@ -302,11 +304,19 @@ try_again: && attr->config == PERF_COUNT_HW_CPU_CYCLES) { if (verbose) - warning(" ... trying to fall back to cpu-clock-ticks\n"); + ui__warning("The cycles event is not supported, " + "trying to fall back to cpu-clock-ticks\n"); attr->type = PERF_TYPE_SOFTWARE; attr->config = PERF_COUNT_SW_CPU_CLOCK; goto try_again; } + + if (err == ENOENT) { + ui__warning("The %s event is not supported.\n", + event_name(pos)); + exit(EXIT_FAILURE); + } + printf("\n"); error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", err, strerror(err)); @@ -506,6 +516,10 @@ static int __cmd_record(int argc, const char **argv) if (have_tracepoints(&evsel_list->entries)) perf_header__set_feat(&session->header, HEADER_TRACE_INFO); + /* 512 kiB: default amount of unprivileged mlocked memory */ + if (mmap_pages == UINT_MAX) + mmap_pages = (512 * 1024) / page_size; + if (forks) { child_pid = fork(); if (child_pid < 0) { diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index b1b82009ab9b..498c6f70a747 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -50,12 +50,12 @@ static symbol_filter_t annotate_init; static int perf_session__add_hist_entry(struct perf_session *session, struct addr_location *al, - struct perf_sample *sample) + struct perf_sample *sample, + struct perf_evsel *evsel) { struct symbol *parent = NULL; int err = 0; struct hist_entry *he; - struct perf_evsel *evsel; if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { err = perf_session__resolve_callchain(session, al->thread, @@ -64,18 +64,6 @@ static int perf_session__add_hist_entry(struct perf_session *session, return err; } - evsel = perf_evlist__id2evsel(session->evlist, sample->id); - if (evsel == NULL) { - /* - * FIXME: Propagate this back, but at least we're in a builtin, - * where exit() is allowed. ;-) - */ - ui__warning("Invalid %s file, contains samples with id %" PRIu64 " not in " - "its header!\n", input_name, sample->id); - exit_browser(0); - exit(1); - } - he = __hists__add_entry(&evsel->hists, al, parent, sample->period); if (he == NULL) return -ENOMEM; @@ -113,6 +101,7 @@ out: static int process_sample_event(union perf_event *event, struct perf_sample *sample, + struct perf_evsel *evsel, struct perf_session *session) { struct addr_location al; @@ -127,7 +116,7 @@ static int process_sample_event(union perf_event *event, if (al.filtered || (hide_unresolved && al.sym == NULL)) return 0; - if (perf_session__add_hist_entry(session, &al, sample)) { + if (perf_session__add_hist_entry(session, &al, sample, evsel)) { pr_debug("problem incrementing symbol period, skipping event\n"); return -1; } diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index a32f411faeac..dcfe8873c9a1 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1603,6 +1603,7 @@ static void process_raw_event(union perf_event *raw_event __used, static int process_sample_event(union perf_event *event, struct perf_sample *sample, + struct perf_evsel *evsel __used, struct perf_session *session) { struct thread *thread; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 9f5fc5492141..ac574ea23917 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -162,19 +162,11 @@ static void print_sample_start(struct perf_sample *sample, static void process_event(union perf_event *event __unused, struct perf_sample *sample, + struct perf_evsel *evsel, struct perf_session *session, struct thread *thread) { - struct perf_event_attr *attr; - struct perf_evsel *evsel; - - evsel = perf_evlist__id2evsel(session->evlist, sample->id); - if (evsel == NULL) { - pr_err("Invalid data. Contains samples with id not in " - "its header!\n"); - return; - } - attr = &evsel->attr; + struct perf_event_attr *attr = &evsel->attr; if (output_fields[attr->type] == 0) return; @@ -244,6 +236,7 @@ static char const *input_name = "perf.data"; static int process_sample_event(union perf_event *event, struct perf_sample *sample, + struct perf_evsel *evsel, struct perf_session *session) { struct thread *thread = perf_session__findnew(session, event->ip.pid); @@ -264,7 +257,7 @@ static int process_sample_event(union perf_event *event, last_timestamp = sample->time; return 0; } - scripting_ops->process_event(event, sample, session, thread); + scripting_ops->process_event(event, sample, evsel, session, thread); session->hists.stats.total_period += sample->period; return 0; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index e2109f9b43eb..03f0e45f1479 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -167,16 +167,17 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; + attr->inherit = !no_inherit; + if (system_wide) - return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, false, false); + return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, false); - attr->inherit = !no_inherit; if (target_pid == -1 && target_tid == -1) { attr->disabled = 1; attr->enable_on_exec = 1; } - return perf_evsel__open_per_thread(evsel, evsel_list->threads, false, false); + return perf_evsel__open_per_thread(evsel, evsel_list->threads, false); } /* diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 1b2106c58f66..11e3c8458362 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -290,7 +290,7 @@ static int test__open_syscall_event(void) goto out_thread_map_delete; } - if (perf_evsel__open_per_thread(evsel, threads, false, false) < 0) { + if (perf_evsel__open_per_thread(evsel, threads, false) < 0) { pr_debug("failed to open counter: %s, " "tweak /proc/sys/kernel/perf_event_paranoid?\n", strerror(errno)); @@ -303,7 +303,7 @@ static int test__open_syscall_event(void) } if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) { - pr_debug("perf_evsel__open_read_on_cpu\n"); + pr_debug("perf_evsel__read_on_cpu\n"); goto out_close_fd; } @@ -365,7 +365,7 @@ static int test__open_syscall_event_on_all_cpus(void) goto out_thread_map_delete; } - if (perf_evsel__open(evsel, cpus, threads, false, false) < 0) { + if (perf_evsel__open(evsel, cpus, threads, false) < 0) { pr_debug("failed to open counter: %s, " "tweak /proc/sys/kernel/perf_event_paranoid?\n", strerror(errno)); @@ -418,7 +418,7 @@ static int test__open_syscall_event_on_all_cpus(void) continue; if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) { - pr_debug("perf_evsel__open_read_on_cpu\n"); + pr_debug("perf_evsel__read_on_cpu\n"); err = -1; break; } @@ -529,7 +529,7 @@ static int test__basic_mmap(void) perf_evlist__add(evlist, evsels[i]); - if (perf_evsel__open(evsels[i], cpus, threads, false, false) < 0) { + if (perf_evsel__open(evsels[i], cpus, threads, false) < 0) { pr_debug("failed to open counter: %s, " "tweak /proc/sys/kernel/perf_event_paranoid?\n", strerror(errno)); diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 67c0459dc325..aa26f4d66d10 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -488,6 +488,7 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te) static int process_sample_event(union perf_event *event __used, struct perf_sample *sample, + struct perf_evsel *evsel __used, struct perf_session *session) { struct trace_entry *te; @@ -506,6 +507,16 @@ static int process_sample_event(union perf_event *event __used, struct power_entry_old *peo; peo = (void *)te; #endif + /* + * FIXME: use evsel, its already mapped from id to perf_evsel, + * remove perf_header__find_event infrastructure bits. + * Mapping all these "power:cpu_idle" strings to the tracepoint + * ID and then just comparing against evsel->attr.config. + * + * e.g.: + * + * if (evsel->attr.config == power_cpu_idle_id) + */ event_str = perf_header__find_event(te->type); if (!event_str) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 70f1075cc5b0..7e3d6e310bf8 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -515,7 +515,9 @@ static void handle_keypress(struct perf_session *session, int c) break; case 'E': if (top.evlist->nr_entries > 1) { - int counter; + /* Select 0 as the default event: */ + int counter = 0; + fprintf(stderr, "\nAvailable events:"); list_for_each_entry(top.sym_evsel, &top.evlist->entries, node) @@ -843,15 +845,16 @@ static void start_counters(struct perf_evlist *evlist) } attr->mmap = 1; + attr->inherit = inherit; try_again: if (perf_evsel__open(counter, top.evlist->cpus, - top.evlist->threads, group, inherit) < 0) { + top.evlist->threads, group) < 0) { int err = errno; - if (err == EPERM || err == EACCES) - die("Permission error - are you root?\n" - "\t Consider tweaking" - " /proc/sys/kernel/perf_event_paranoid.\n"); + if (err == EPERM || err == EACCES) { + ui__warning_paranoid(); + goto out_err; + } /* * If it's cycles then fall back to hrtimer * based cpu-clock-tick sw counter, which @@ -859,25 +862,41 @@ try_again: */ if (attr->type == PERF_TYPE_HARDWARE && attr->config == PERF_COUNT_HW_CPU_CYCLES) { - if (verbose) - warning(" ... trying to fall back to cpu-clock-ticks\n"); + ui__warning("Cycles event not supported,\n" + "trying to fall back to cpu-clock-ticks\n"); attr->type = PERF_TYPE_SOFTWARE; attr->config = PERF_COUNT_SW_CPU_CLOCK; goto try_again; } - printf("\n"); - error("sys_perf_event_open() syscall returned with %d " - "(%s). /bin/dmesg may provide additional information.\n", - err, strerror(err)); - die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); - exit(-1); + + if (err == ENOENT) { + ui__warning("The %s event is not supported.\n", + event_name(counter)); + goto out_err; + } + + ui__warning("The sys_perf_event_open() syscall " + "returned with %d (%s). /bin/dmesg " + "may provide additional information.\n" + "No CONFIG_PERF_EVENTS=y kernel support " + "configured?\n", err, strerror(err)); + goto out_err; } } - if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) - die("failed to mmap with %d (%s)\n", errno, strerror(errno)); + if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) { + ui__warning("Failed to mmap with %d (%s)\n", + errno, strerror(errno)); + goto out_err; + } + + return; + +out_err: + exit_browser(0); + exit(0); } static int __cmd_top(void) diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 31f934af9861..a91cd99f26ea 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -16,6 +16,7 @@ static int build_id__mark_dso_hit(union perf_event *event, struct perf_sample *sample __used, + struct perf_evsel *evsel __used, struct perf_session *session) { struct addr_location al; diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 9fea75535221..96bee5c46008 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -13,7 +13,7 @@ cgroupfs_find_mountpoint(char *buf, size_t maxlen) { FILE *fp; char mountpoint[MAX_PATH+1], tokens[MAX_PATH+1], type[MAX_PATH+1]; - char *token, *saved_ptr; + char *token, *saved_ptr = NULL; int found = 0; fp = fopen("/proc/mounts", "r"); diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index d4536a9e0d8c..155749d74350 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -57,6 +57,16 @@ void ui__warning(const char *format, ...) } #endif +void ui__warning_paranoid(void) +{ + ui__warning("Permission error - are you root?\n" + "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" + " -1 - Not paranoid at all\n" + " 0 - Disallow raw tracepoint access for unpriv\n" + " 1 - Disallow cpu events for unpriv\n" + " 2 - Disallow kernel profiling for unpriv\n"); +} + void trace_event(union perf_event *event) { unsigned char *raw_event = (void *)event; diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 93516cf4682c..fd53db47e3de 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -36,5 +36,6 @@ int ui_helpline__show_help(const char *format, va_list ap); #endif void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); +void ui__warning_paranoid(void); #endif /* __PERF_DEBUG_H */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2b15c362ef56..1023f67633a4 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -710,7 +710,7 @@ try_again: * in the whole kernel symbol list. */ if ((long long)al->addr < 0 && - cpumode == PERF_RECORD_MISC_KERNEL && + cpumode == PERF_RECORD_MISC_USER && machine && mg != &machine->kmaps) { mg = &machine->kmaps; goto try_again; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d852cefa20de..45da8d186b49 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -12,6 +12,7 @@ #include "evlist.h" #include "evsel.h" #include "util.h" +#include "debug.h" #include <sys/mman.h> @@ -250,15 +251,19 @@ int perf_evlist__alloc_mmap(struct perf_evlist *evlist) return evlist->mmap != NULL ? 0 : -ENOMEM; } -static int __perf_evlist__mmap(struct perf_evlist *evlist, int cpu, int prot, - int mask, int fd) +static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel, + int cpu, int prot, int mask, int fd) { evlist->mmap[cpu].prev = 0; evlist->mmap[cpu].mask = mask; evlist->mmap[cpu].base = mmap(NULL, evlist->mmap_len, prot, MAP_SHARED, fd, 0); - if (evlist->mmap[cpu].base == MAP_FAILED) + if (evlist->mmap[cpu].base == MAP_FAILED) { + if (evlist->cpus->map[cpu] == -1 && evsel->attr.inherit) + ui__warning("Inherit is not allowed on per-task " + "events using mmap.\n"); return -1; + } perf_evlist__add_pollfd(evlist, fd); return 0; @@ -312,7 +317,8 @@ int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, FD(first_evsel, cpu, 0)) != 0) goto out_unmap; - } else if (__perf_evlist__mmap(evlist, cpu, prot, mask, fd) < 0) + } else if (__perf_evlist__mmap(evlist, evsel, cpu, + prot, mask, fd) < 0) goto out_unmap; if ((evsel->attr.read_format & PERF_FORMAT_ID) && diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 662596afd7f1..d6fd59beb860 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -175,7 +175,7 @@ int __perf_evsel__read(struct perf_evsel *evsel, } static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, - struct thread_map *threads, bool group, bool inherit) + struct thread_map *threads, bool group) { int cpu, thread; unsigned long flags = 0; @@ -192,19 +192,6 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, for (cpu = 0; cpu < cpus->nr; cpu++) { int group_fd = -1; - /* - * Don't allow mmap() of inherited per-task counters. This - * would create a performance issue due to all children writing - * to the same buffer. - * - * FIXME: - * Proper fix is not to pass 'inherit' to perf_evsel__open*, - * but a 'flags' parameter, with 'group' folded there as well, - * then introduce a PERF_O_{MMAP,GROUP,INHERIT} enum, and if - * O_MMAP is set, emit a warning if cpu < 0 and O_INHERIT is - * set. Lets go for the minimal fix first tho. - */ - evsel->attr.inherit = (cpus->map[cpu] >= 0) && inherit; for (thread = 0; thread < threads->nr; thread++) { @@ -253,7 +240,7 @@ static struct { }; int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, - struct thread_map *threads, bool group, bool inherit) + struct thread_map *threads, bool group) { if (cpus == NULL) { /* Work around old compiler warnings about strict aliasing */ @@ -263,19 +250,19 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, if (threads == NULL) threads = &empty_thread_map.map; - return __perf_evsel__open(evsel, cpus, threads, group, inherit); + return __perf_evsel__open(evsel, cpus, threads, group); } int perf_evsel__open_per_cpu(struct perf_evsel *evsel, - struct cpu_map *cpus, bool group, bool inherit) + struct cpu_map *cpus, bool group) { - return __perf_evsel__open(evsel, cpus, &empty_thread_map.map, group, inherit); + return __perf_evsel__open(evsel, cpus, &empty_thread_map.map, group); } int perf_evsel__open_per_thread(struct perf_evsel *evsel, - struct thread_map *threads, bool group, bool inherit) + struct thread_map *threads, bool group) { - return __perf_evsel__open(evsel, &empty_cpu_map.map, threads, group, inherit); + return __perf_evsel__open(evsel, &empty_cpu_map.map, threads, group); } static int perf_event__parse_id_sample(const union perf_event *event, u64 type, diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 6710ab538342..f79bb2c09a6c 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -81,11 +81,11 @@ void perf_evsel__free_id(struct perf_evsel *evsel); void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads); int perf_evsel__open_per_cpu(struct perf_evsel *evsel, - struct cpu_map *cpus, bool group, bool inherit); + struct cpu_map *cpus, bool group); int perf_evsel__open_per_thread(struct perf_evsel *evsel, - struct thread_map *threads, bool group, bool inherit); + struct thread_map *threads, bool group); int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, - struct thread_map *threads, bool group, bool inherit); + struct thread_map *threads, bool group); #define perf_evsel__match(evsel, t, c) \ (evsel->attr.type == PERF_TYPE_##t && \ diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index e5230c0ef95b..93862a8027ea 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -695,13 +695,50 @@ out: return err; } +static int perf_header__read_build_ids_abi_quirk(struct perf_header *header, + int input, u64 offset, u64 size) +{ + struct perf_session *session = container_of(header, struct perf_session, header); + struct { + struct perf_event_header header; + u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))]; + char filename[0]; + } old_bev; + struct build_id_event bev; + char filename[PATH_MAX]; + u64 limit = offset + size; + + while (offset < limit) { + ssize_t len; + + if (read(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev)) + return -1; + + if (header->needs_swap) + perf_event_header__bswap(&old_bev.header); + + len = old_bev.header.size - sizeof(old_bev); + if (read(input, filename, len) != len) + return -1; + + bev.header = old_bev.header; + bev.pid = 0; + memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id)); + __event_process_build_id(&bev, filename, session); + + offset += bev.header.size; + } + + return 0; +} + static int perf_header__read_build_ids(struct perf_header *header, int input, u64 offset, u64 size) { struct perf_session *session = container_of(header, struct perf_session, header); struct build_id_event bev; char filename[PATH_MAX]; - u64 limit = offset + size; + u64 limit = offset + size, orig_offset = offset; int err = -1; while (offset < limit) { @@ -716,6 +753,24 @@ static int perf_header__read_build_ids(struct perf_header *header, len = bev.header.size - sizeof(bev); if (read(input, filename, len) != len) goto out; + /* + * The a1645ce1 changeset: + * + * "perf: 'perf kvm' tool for monitoring guest performance from host" + * + * Added a field to struct build_id_event that broke the file + * format. + * + * Since the kernel build-id is the first entry, process the + * table using the old format if the well known + * '[kernel.kallsyms]' string for the kernel build-id has the + * first 4 characters chopped off (where the pid_t sits). + */ + if (memcmp(filename, "nel.kallsyms]", 13) == 0) { + if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1) + return -1; + return perf_header__read_build_ids_abi_quirk(header, input, offset, size); + } __event_process_build_id(&bev, filename, session); diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index cb6858a2f9a3..3beb97c4d822 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -29,6 +29,7 @@ struct events_stats { u32 nr_events[PERF_RECORD_HEADER_MAX]; u32 nr_unknown_events; u32 nr_invalid_chains; + u32 nr_unknown_id; }; enum hist_column { diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 5ddee66020a7..f0223166e761 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -234,7 +234,6 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, /* Searching trace events corresponding to probe event */ ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs); - close(fd); if (ntevs > 0) { /* Succeeded to find trace events */ pr_debug("find %d probe_trace_events.\n", ntevs); @@ -388,7 +387,6 @@ int show_line_range(struct line_range *lr, const char *module) } ret = find_line_range(fd, lr); - close(fd); if (ret == 0) { pr_warning("Specified source line is not found.\n"); return -ENOENT; @@ -512,19 +510,18 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, if (ret < 0) return ret; - fd = open_vmlinux(module); - if (fd < 0) { - pr_warning("Failed to open debug information file.\n"); - return fd; - } - setup_pager(); - for (i = 0; i < npevs && ret >= 0; i++) + for (i = 0; i < npevs && ret >= 0; i++) { + fd = open_vmlinux(module); + if (fd < 0) { + pr_warning("Failed to open debug information file.\n"); + ret = fd; + break; + } ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter, externs); - - close(fd); + } return ret; } diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 194f9e2a3285..b7c85ce466a1 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -273,6 +273,25 @@ static const char *cu_get_comp_dir(Dwarf_Die *cu_die) return dwarf_formstring(&attr); } +/* Get a line number and file name for given address */ +static int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr, + const char **fname, int *lineno) +{ + Dwarf_Line *line; + Dwarf_Addr laddr; + + line = dwarf_getsrc_die(cudie, (Dwarf_Addr)addr); + if (line && dwarf_lineaddr(line, &laddr) == 0 && + addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) { + *fname = dwarf_linesrc(line, NULL, NULL); + if (!*fname) + /* line number is useless without filename */ + *lineno = 0; + } + + return *lineno ?: -ENOENT; +} + /* Compare diename and tname */ static bool die_compare_name(Dwarf_Die *dw_die, const char *tname) { @@ -497,7 +516,20 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, Dwarf_Die *die_mem) { - return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); + Dwarf_Die tmp_die; + + sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die); + if (!sp_die) + return NULL; + + /* Inlined function could be recursive. Trace it until fail */ + while (sp_die) { + memcpy(die_mem, sp_die, sizeof(Dwarf_Die)); + sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, + &tmp_die); + } + + return die_mem; } /* Walker on lines (Note: line number will not be sorted) */ @@ -1395,6 +1427,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) !die_compare_name(sp_die, pp->function)) return DWARF_CB_OK; + /* Check declared file */ + if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die))) + return DWARF_CB_OK; + pf->fname = dwarf_decl_file(sp_die); if (pp->line) { /* Function relative line */ dwarf_decl_line(sp_die, &pf->lno); @@ -1451,6 +1487,7 @@ static int find_probes(int fd, struct probe_finder *pf) if (!dbg) { pr_warning("No debug information found in the vmlinux - " "please rebuild with CONFIG_DEBUG_INFO=y.\n"); + close(fd); /* Without dwfl_end(), fd isn't closed. */ return -EBADF; } @@ -1686,11 +1723,9 @@ int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt) Dwarf_Die cudie, spdie, indie; Dwarf *dbg = NULL; Dwfl *dwfl = NULL; - Dwarf_Line *line; - Dwarf_Addr laddr, eaddr, bias = 0; - const char *tmp; - int lineno, ret = 0; - bool found = false; + Dwarf_Addr _addr, baseaddr, bias = 0; + const char *fname = NULL, *func = NULL, *tmp; + int baseline = 0, lineno = 0, ret = 0; /* Open the live linux kernel */ dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias); @@ -1711,68 +1746,79 @@ int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt) goto end; } - /* Find a corresponding line */ - line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr); - if (line) { - if (dwarf_lineaddr(line, &laddr) == 0 && - (Dwarf_Addr)addr == laddr && - dwarf_lineno(line, &lineno) == 0) { - tmp = dwarf_linesrc(line, NULL, NULL); - if (tmp) { - ppt->line = lineno; - ppt->file = strdup(tmp); - if (ppt->file == NULL) { - ret = -ENOMEM; - goto end; - } - found = true; - } - } - } + /* Find a corresponding line (filename and lineno) */ + cu_find_lineinfo(&cudie, addr, &fname, &lineno); + /* Don't care whether it failed or not */ - /* Find a corresponding function */ + /* Find a corresponding function (name, baseline and baseaddr) */ if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) { + /* Get function entry information */ tmp = dwarf_diename(&spdie); - if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0) - goto end; - - if (ppt->line) { - if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, - &indie)) { - /* addr in an inline function */ + if (!tmp || + dwarf_entrypc(&spdie, &baseaddr) != 0 || + dwarf_decl_line(&spdie, &baseline) != 0) + goto post; + func = tmp; + + if (addr == (unsigned long)baseaddr) + /* Function entry - Relative line number is 0 */ + lineno = baseline; + else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, + &indie)) { + if (dwarf_entrypc(&indie, &_addr) == 0 && + _addr == addr) + /* + * addr is at an inline function entry. + * In this case, lineno should be the call-site + * line number. + */ + lineno = die_get_call_lineno(&indie); + else { + /* + * addr is in an inline function body. + * Since lineno points one of the lines + * of the inline function, baseline should + * be the entry line of the inline function. + */ tmp = dwarf_diename(&indie); - if (!tmp) - goto end; - ret = dwarf_decl_line(&indie, &lineno); - } else { - if (eaddr == addr) { /* Function entry */ - lineno = ppt->line; - ret = 0; - } else - ret = dwarf_decl_line(&spdie, &lineno); - } - if (ret == 0) { - /* Make a relative line number */ - ppt->line -= lineno; - goto found; + if (tmp && + dwarf_decl_line(&spdie, &baseline) == 0) + func = tmp; } } - /* We don't have a line number, let's use offset */ - ppt->offset = addr - (unsigned long)eaddr; -found: - ppt->function = strdup(tmp); + } + +post: + /* Make a relative line number or an offset */ + if (lineno) + ppt->line = lineno - baseline; + else if (func) + ppt->offset = addr - (unsigned long)baseaddr; + + /* Duplicate strings */ + if (func) { + ppt->function = strdup(func); if (ppt->function == NULL) { ret = -ENOMEM; goto end; } - found = true; } - + if (fname) { + ppt->file = strdup(fname); + if (ppt->file == NULL) { + if (ppt->function) { + free(ppt->function); + ppt->function = NULL; + } + ret = -ENOMEM; + goto end; + } + } end: if (dwfl) dwfl_end(dwfl); - if (ret >= 0) - ret = found ? 1 : 0; + if (ret == 0 && (fname || func)) + ret = 1; /* Found a point */ return ret; } @@ -1840,6 +1886,10 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data) struct line_finder *lf = param->data; struct line_range *lr = lf->lr; + /* Check declared file */ + if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die))) + return DWARF_CB_OK; + if (dwarf_tag(sp_die) == DW_TAG_subprogram && die_compare_name(sp_die, lr->function)) { lf->fname = dwarf_decl_file(sp_die); @@ -1892,6 +1942,7 @@ int find_line_range(int fd, struct line_range *lr) if (!dbg) { pr_warning("No debug information found in the vmlinux - " "please rebuild with CONFIG_DEBUG_INFO=y.\n"); + close(fd); /* Without dwfl_end(), fd isn't closed. */ return -EBADF; } diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index a9f2d7e1204d..f5e38451fdc5 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -498,11 +498,11 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, struct cpu_map *cpus = NULL; struct thread_map *threads = NULL; PyObject *pcpus = NULL, *pthreads = NULL; - int group = 0, overwrite = 0; - static char *kwlist[] = {"cpus", "threads", "group", "overwrite", NULL, NULL}; + int group = 0, inherit = 0; + static char *kwlist[] = {"cpus", "threads", "group", "inherit", NULL, NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, - &pcpus, &pthreads, &group, &overwrite)) + &pcpus, &pthreads, &group, &inherit)) return NULL; if (pthreads != NULL) @@ -511,7 +511,8 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, if (pcpus != NULL) cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; - if (perf_evsel__open(evsel, cpus, threads, group, overwrite) < 0) { + evsel->attr.inherit = inherit; + if (perf_evsel__open(evsel, cpus, threads, group) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 621427212e86..74350ffb57fe 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -247,6 +247,7 @@ static inline struct event *find_cache_event(int type) static void perl_process_event(union perf_event *pevent __unused, struct perf_sample *sample, + struct perf_evsel *evsel, struct perf_session *session __unused, struct thread *thread) { diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 1b85d6055159..6ccf70e8d8f2 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -206,6 +206,7 @@ static inline struct event *find_cache_event(int type) static void python_process_event(union perf_event *pevent __unused, struct perf_sample *sample, + struct perf_evsel *evsel __unused, struct perf_session *session __unused, struct thread *thread) { diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index c68cf40764f9..caa224522fea 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -280,6 +280,15 @@ static int process_event_synth_stub(union perf_event *event __used, return 0; } +static int process_event_sample_stub(union perf_event *event __used, + struct perf_sample *sample __used, + struct perf_evsel *evsel __used, + struct perf_session *session __used) +{ + dump_printf(": unhandled!\n"); + return 0; +} + static int process_event_stub(union perf_event *event __used, struct perf_sample *sample __used, struct perf_session *session __used) @@ -303,7 +312,7 @@ static int process_finished_round(union perf_event *event, static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) { if (handler->sample == NULL) - handler->sample = process_event_stub; + handler->sample = process_event_sample_stub; if (handler->mmap == NULL) handler->mmap = process_event_stub; if (handler->comm == NULL) @@ -698,12 +707,19 @@ static int perf_session_deliver_event(struct perf_session *session, struct perf_event_ops *ops, u64 file_offset) { + struct perf_evsel *evsel; + dump_event(session, event, file_offset, sample); switch (event->header.type) { case PERF_RECORD_SAMPLE: dump_sample(session, event, sample); - return ops->sample(event, sample, session); + evsel = perf_evlist__id2evsel(session->evlist, sample->id); + if (evsel == NULL) { + ++session->hists.stats.nr_unknown_id; + return -1; + } + return ops->sample(event, sample, evsel, session); case PERF_RECORD_MMAP: return ops->mmap(event, sample, session); case PERF_RECORD_COMM: @@ -845,6 +861,11 @@ static void perf_session__warn_about_errors(const struct perf_session *session, session->hists.stats.nr_unknown_events); } + if (session->hists.stats.nr_unknown_id != 0) { + ui__warning("%u samples with id not present in the header\n", + session->hists.stats.nr_unknown_id); + } + if (session->hists.stats.nr_invalid_chains != 0) { ui__warning("Found invalid callchains!\n\n" "%u out of %u events were discarded for this reason.\n\n" diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 0b3c9afecaa9..1ac481fc1100 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -55,8 +55,11 @@ struct perf_session { char filename[0]; }; +struct perf_evsel; struct perf_event_ops; +typedef int (*event_sample)(union perf_event *event, struct perf_sample *sample, + struct perf_evsel *evsel, struct perf_session *session); typedef int (*event_op)(union perf_event *self, struct perf_sample *sample, struct perf_session *session); typedef int (*event_synth_op)(union perf_event *self, @@ -65,8 +68,8 @@ typedef int (*event_op2)(union perf_event *self, struct perf_session *session, struct perf_event_ops *ops); struct perf_event_ops { - event_op sample, - mmap, + event_sample sample; + event_op mmap, comm, fork, exit, diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index e24ffadb20b2..bbc982f5dd8b 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py @@ -1,13 +1,18 @@ #!/usr/bin/python2 from distutils.core import setup, Extension +from os import getenv + +cflags = ['-fno-strict-aliasing', '-Wno-write-strings'] +cflags += getenv('CFLAGS', '').split() perf = Extension('perf', sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c', 'util/util.c', 'util/xyarray.c', 'util/cgroup.c'], include_dirs = ['util/include'], - extra_compile_args = ['-fno-strict-aliasing', '-Wno-write-strings']) + extra_compile_args = cflags, + ) setup(name='perf', version='0.1', diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 8fc0bd3a3a4a..b9a985dadd08 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c @@ -85,7 +85,7 @@ out: /* * Helper function for splitting a string into an argv-like array. - * originaly copied from lib/argv_split.c + * originally copied from lib/argv_split.c */ static const char *skip_sep(const char *cp) { diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 651dbfe7f4f3..f06c10f092ba 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1196,6 +1196,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, if (curr_dso == NULL) goto out_elf_end; curr_dso->kernel = self->kernel; + curr_dso->long_name = self->long_name; + curr_dso->long_name_len = self->long_name_len; curr_map = map__new2(start, curr_dso, map->type); if (curr_map == NULL) { @@ -1486,7 +1488,9 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) * On the first pass, only load images if they have a full symtab. * Failing that, do a second pass where we accept .dynsym also */ - for (self->symtab_type = SYMTAB__BUILD_ID_CACHE, want_symtab = 1; + want_symtab = 1; +restart: + for (self->symtab_type = SYMTAB__BUILD_ID_CACHE; self->symtab_type != SYMTAB__NOT_FOUND; self->symtab_type++) { switch (self->symtab_type) { @@ -1536,17 +1540,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) snprintf(name, size, "%s%s", symbol_conf.symfs, self->long_name); break; - - default: - /* - * If we wanted a full symtab but no image had one, - * relax our requirements and repeat the search. - */ - if (want_symtab) { - want_symtab = 0; - self->symtab_type = SYMTAB__BUILD_ID_CACHE; - } else - continue; + default:; } /* Name is now the name of the next image to try */ @@ -1573,6 +1567,15 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) } } + /* + * If we wanted a full symtab but no image had one, + * relax our requirements and repeat the search. + */ + if (ret <= 0 && want_symtab) { + want_symtab = 0; + goto restart; + } + free(name); if (ret < 0 && strstr(self->name, " (deleted)") != NULL) return 0; @@ -1841,6 +1844,7 @@ int dso__load_vmlinux(struct dso *self, struct map *map, if (fd < 0) return -1; + dso__set_long_name(self, (char *)vmlinux); dso__set_loaded(self, map->type); err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); close(fd); @@ -2402,6 +2406,8 @@ int symbol__init(void) if (symbol_conf.initialized) return 0; + symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64)); + elf_version(EV_CURRENT); if (symbol_conf.sort_by_name) symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 66f4b78737ab..c9dcbec7d800 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -38,6 +38,7 @@ static int stop_script_unsupported(void) static void process_event_unsupported(union perf_event *event __unused, struct perf_sample *sample __unused, + struct perf_evsel *evsel __unused, struct perf_session *session __unused, struct thread *thread __unused) { diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index b04da5722437..f674dda3363b 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -280,6 +280,7 @@ struct scripting_ops { int (*stop_script) (void); void (*process_event) (union perf_event *event, struct perf_sample *sample, + struct perf_evsel *evsel, struct perf_session *session, struct thread *thread); int (*generate_script) (const char *outfile); diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 8c17a8730e4a..15633d608133 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c @@ -256,10 +256,9 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, int refresh) { struct objdump_line *pos, *n; - struct annotation *notes = symbol__annotation(sym); + struct annotation *notes; struct annotate_browser browser = { .b = { - .entries = ¬es->src->source, .refresh = ui_browser__list_head_refresh, .seek = ui_browser__list_head_seek, .write = annotate_browser__write, @@ -281,6 +280,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, ui_helpline__push("Press <- or ESC to exit"); + notes = symbol__annotation(sym); + list_for_each_entry(pos, ¬es->src->source, node) { struct objdump_line_rb_node *rbpos; size_t line_len = strlen(pos->line); @@ -291,6 +292,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, rbpos->idx = browser.b.nr_entries++; } + browser.b.entries = ¬es->src->source, browser.b.width += 18; /* Percentage */ ret = annotate_browser__run(&browser, evidx, refresh); list_for_each_entry_safe(pos, n, ¬es->src->source, node) { diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index 798efdca3ead..5d767c622dfc 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c @@ -851,7 +851,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, goto out_free_stack; case 'a': if (browser->selection == NULL || - browser->selection->map == NULL || + browser->selection->sym == NULL || browser->selection->map->dso->annotate_warned) continue; goto do_annotate; diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c index d9678a34dd70..2618ef2ba31f 100644 --- a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c +++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c @@ -46,7 +46,7 @@ int cpu = -1; * * performance * Performance is paramount. - * Unwilling to sacrafice any performance + * Unwilling to sacrifice any performance * for the sake of energy saving. (hardware default) * * normal |