diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-22 20:37:20 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-22 20:37:20 (GMT) |
commit | 727cde6c3af38ebb2dbc40e0b32499a55051851d (patch) | |
tree | 75cb0a199638a1aef4f165f9b603871499aed717 | |
parent | 069ec22915b0932e1c2da53255a705593743374f (diff) | |
parent | e15bf88a44d1fcb685754b2868b1cd28927af3aa (diff) | |
download | linux-727cde6c3af38ebb2dbc40e0b32499a55051851d.tar.xz |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf tool fixes from Thomas Gleixner:
"A couple of fixes for perf tools:
- Build system updates
- Plug a memory leak in an error path of perf probe
- Tear down probes correctly when adding fails
- Fixes to the perf symbol handling
- Fix ordering of event processing in buildid-list
- Fix per DSO filtering in the histogram browser"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf probe: Clear probe_trace_event when add_probe_trace_event() fails
perf probe: Fix memory leaking on failure by clearing all probe_trace_events
perf inject: Also re-pipe lost_samples event
perf buildid-list: Requires ordered events
perf symbols: Fix dso lookup by long name and missing buildids
perf symbols: Allow forcing reading of non-root owned files by root
perf hists browser: The dso can be obtained from popup_action->ms.map->dso
perf hists browser: Fix 'd' hotkey action to filter by DSO
perf symbols: Rebuild rbtree when adjusting symbols for kcore
tools: Add a "make all" rule
tools: Actually install tmon in the install rule
-rw-r--r-- | tools/Makefile | 11 | ||||
-rw-r--r-- | tools/perf/builtin-inject.c | 1 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 6 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 7 | ||||
-rw-r--r-- | tools/perf/util/build-id.c | 1 | ||||
-rw-r--r-- | tools/perf/util/dso.c | 17 | ||||
-rw-r--r-- | tools/perf/util/dso.h | 1 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 1 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 24 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 34 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 1 |
11 files changed, 69 insertions, 35 deletions
diff --git a/tools/Makefile b/tools/Makefile index d6f307d..7dc820a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -32,6 +32,10 @@ help: @echo ' from the kernel command line to build and install one of' @echo ' the tools above' @echo '' + @echo ' $$ make tools/all' + @echo '' + @echo ' builds all tools.' + @echo '' @echo ' $$ make tools/install' @echo '' @echo ' installs all tools.' @@ -77,6 +81,11 @@ tmon: FORCE freefall: FORCE $(call descend,laptop/$@) +all: acpi cgroup cpupower hv firewire lguest \ + perf selftests turbostat usb \ + virtio vm net x86_energy_perf_policy \ + tmon freefall + acpi_install: $(call descend,power/$(@:_install=),install) @@ -101,7 +110,7 @@ freefall_install: install: acpi_install cgroup_install cpupower_install hv_install firewire_install lguest_install \ perf_install selftests_install turbostat_install usb_install \ virtio_install vm_install net_install x86_energy_perf_policy_install \ - tmon freefall_install + tmon_install freefall_install acpi_clean: $(call descend,power/acpi,clean) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 0a945d2..99d127f 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -675,6 +675,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) .fork = perf_event__repipe, .exit = perf_event__repipe, .lost = perf_event__repipe, + .lost_samples = perf_event__repipe, .aux = perf_event__repipe, .itrace_start = perf_event__repipe, .context_switch = perf_event__repipe, diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2853ad2..f256fac 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -44,7 +44,7 @@ struct report { struct perf_tool tool; struct perf_session *session; - bool force, use_tui, use_gtk, use_stdio; + bool use_tui, use_gtk, use_stdio; bool hide_unresolved; bool dont_use_callchains; bool show_full_info; @@ -678,7 +678,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) "file", "vmlinux pathname"), OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file", "kallsyms pathname"), - OPT_BOOLEAN('f', "force", &report.force, "don't complain, do it"), + OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, "load module symbols - WARNING: use only with -k and LIVE kernel"), OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, @@ -832,7 +832,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) } file.path = input_name; - file.force = report.force; + file.force = symbol_conf.force; repeat: session = perf_session__new(&file, false, &report.tool); diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index e5afb89..fa9eb92 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1430,7 +1430,6 @@ close_file_and_continue: struct popup_action { struct thread *thread; - struct dso *dso; struct map_symbol ms; int socket; @@ -1565,7 +1564,6 @@ add_dso_opt(struct hist_browser *browser, struct popup_action *act, return 0; act->ms.map = map; - act->dso = map->dso; act->fn = do_zoom_dso; return 1; } @@ -1827,7 +1825,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, while (1) { struct thread *thread = NULL; - struct dso *dso = NULL; struct map *map = NULL; int choice = 0; int socked_id = -1; @@ -1839,8 +1836,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, if (browser->he_selection != NULL) { thread = hist_browser__selected_thread(browser); map = browser->selection->map; - if (map) - dso = map->dso; socked_id = browser->he_selection->socket; } switch (key) { @@ -1874,7 +1869,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, hist_browser__dump(browser); continue; case 'd': - actions->dso = dso; + actions->ms.map = map; do_zoom_dso(browser, actions); continue; case 'V': diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index d909459..217b5a6 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -76,6 +76,7 @@ struct perf_tool build_id__mark_dso_hit_ops = { .exit = perf_event__exit_del_thread, .attr = perf_event__process_attr, .build_id = perf_event__process_build_id, + .ordered_events = true, }; int build_id__sprintf(const u8 *build_id, int len, char *bf) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 7c0c083..425df5c 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -933,6 +933,7 @@ static struct dso *__dso__findlink_by_longname(struct rb_root *root, /* Add new node and rebalance tree */ rb_link_node(&dso->rb_node, parent, p); rb_insert_color(&dso->rb_node, root); + dso->root = root; } return NULL; } @@ -945,15 +946,30 @@ static inline struct dso *__dso__find_by_longname(struct rb_root *root, void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated) { + struct rb_root *root = dso->root; + if (name == NULL) return; if (dso->long_name_allocated) free((char *)dso->long_name); + if (root) { + rb_erase(&dso->rb_node, root); + /* + * __dso__findlink_by_longname() isn't guaranteed to add it + * back, so a clean removal is required here. + */ + RB_CLEAR_NODE(&dso->rb_node); + dso->root = NULL; + } + dso->long_name = name; dso->long_name_len = strlen(name); dso->long_name_allocated = name_allocated; + + if (root) + __dso__findlink_by_longname(root, dso, NULL); } void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated) @@ -1046,6 +1062,7 @@ struct dso *dso__new(const char *name) dso->kernel = DSO_TYPE_USER; dso->needs_swap = DSO_SWAP__UNSET; RB_CLEAR_NODE(&dso->rb_node); + dso->root = NULL; INIT_LIST_HEAD(&dso->node); INIT_LIST_HEAD(&dso->data.open_entry); pthread_mutex_init(&dso->lock, NULL); diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index fc8db9c..45ec4d0 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -135,6 +135,7 @@ struct dso { pthread_mutex_t lock; struct list_head node; struct rb_node rb_node; /* rbtree node sorted by long name */ + struct rb_root *root; /* root of rbtree that rb_node is in */ struct rb_root symbols[MAP__NR_TYPES]; struct rb_root symbol_names[MAP__NR_TYPES]; struct { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 5ef90be..8b303ff 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -91,6 +91,7 @@ static void dsos__purge(struct dsos *dsos) list_for_each_entry_safe(pos, n, &dsos->head, node) { RB_CLEAR_NODE(&pos->rb_node); + pos->root = NULL; list_del_init(&pos->node); dso__put(pos); } diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index bd8f03d..05012bb 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -1183,7 +1183,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) container_of(pf, struct trace_event_finder, pf); struct perf_probe_point *pp = &pf->pev->point; struct probe_trace_event *tev; - struct perf_probe_arg *args; + struct perf_probe_arg *args = NULL; int ret, i; /* Check number of tevs */ @@ -1198,19 +1198,23 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr, pp->retprobe, pp->function, &tev->point); if (ret < 0) - return ret; + goto end; tev->point.realname = strdup(dwarf_diename(sc_die)); - if (!tev->point.realname) - return -ENOMEM; + if (!tev->point.realname) { + ret = -ENOMEM; + goto end; + } pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, tev->point.offset); /* Expand special probe argument if exist */ args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS); - if (args == NULL) - return -ENOMEM; + if (args == NULL) { + ret = -ENOMEM; + goto end; + } ret = expand_probe_args(sc_die, pf, args); if (ret < 0) @@ -1234,6 +1238,10 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) } end: + if (ret) { + clear_probe_trace_event(tev); + tf->ntevs--; + } free(args); return ret; } @@ -1246,7 +1254,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg, struct trace_event_finder tf = { .pf = {.pev = pev, .callback = add_probe_trace_event}, .max_tevs = probe_conf.max_probes, .mod = dbg->mod}; - int ret; + int ret, i; /* Allocate result tevs array */ *tevs = zalloc(sizeof(struct probe_trace_event) * tf.max_tevs); @@ -1258,6 +1266,8 @@ int debuginfo__find_trace_events(struct debuginfo *dbg, ret = debuginfo__find_probes(dbg, &tf.pf); if (ret < 0) { + for (i = 0; i < tf.ntevs; i++) + clear_probe_trace_event(&tf.tevs[i]); zfree(tevs); return ret; } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b4cc766..cd08027 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -654,19 +654,24 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map, struct map_groups *kmaps = map__kmaps(map); struct map *curr_map; struct symbol *pos; - int count = 0, moved = 0; + int count = 0; + struct rb_root old_root = dso->symbols[map->type]; struct rb_root *root = &dso->symbols[map->type]; struct rb_node *next = rb_first(root); if (!kmaps) return -1; + *root = RB_ROOT; + while (next) { char *module; pos = rb_entry(next, struct symbol, rb_node); next = rb_next(&pos->rb_node); + rb_erase_init(&pos->rb_node, &old_root); + module = strchr(pos->name, '\t'); if (module) *module = '\0'; @@ -674,28 +679,21 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map, curr_map = map_groups__find(kmaps, map->type, pos->start); if (!curr_map || (filter && filter(curr_map, pos))) { - rb_erase_init(&pos->rb_node, root); symbol__delete(pos); - } else { - pos->start -= curr_map->start - curr_map->pgoff; - if (pos->end) - pos->end -= curr_map->start - curr_map->pgoff; - if (curr_map->dso != map->dso) { - rb_erase_init(&pos->rb_node, root); - symbols__insert( - &curr_map->dso->symbols[curr_map->type], - pos); - ++moved; - } else { - ++count; - } + continue; } + + pos->start -= curr_map->start - curr_map->pgoff; + if (pos->end) + pos->end -= curr_map->start - curr_map->pgoff; + symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); + ++count; } /* Symbols have been adjusted */ dso->adjust_symbols = 1; - return count + moved; + return count; } /* @@ -1438,9 +1436,9 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) if (lstat(dso->name, &st) < 0) goto out; - if (st.st_uid && (st.st_uid != geteuid())) { + if (!symbol_conf.force && st.st_uid && (st.st_uid != geteuid())) { pr_warning("File %s not owned by current user or root, " - "ignoring it.\n", dso->name); + "ignoring it (use -f to override).\n", dso->name); goto out; } diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 40073c6..dcd786e 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -84,6 +84,7 @@ struct symbol_conf { unsigned short priv_size; unsigned short nr_events; bool try_vmlinux_path, + force, ignore_vmlinux, ignore_vmlinux_buildid, show_kernel_path, |