Linus,

please pull the latest perf-urgent-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 
perf-urgent-for-linus

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

Thanks,

        tglx

------------------>
Adrian Hunter (4):
      perf symbols: Rebuild rbtree when adjusting symbols for kcore
      perf symbols: Fix dso lookup by long name and missing buildids
      perf buildid-list: Requires ordered events
      perf inject: Also re-pipe lost_samples event

Arnaldo Carvalho de Melo (3):
      perf hists browser: Fix 'd' hotkey action to filter by DSO
      perf hists browser: The dso can be obtained from popup_action->ms.map->dso
      perf symbols: Allow forcing reading of non-root owned files by root

Kamal Mostafa (2):
      tools: Actually install tmon in the install rule
      tools: Add a "make all" rule

Masami Hiramatsu (1):
      perf probe: Fix memory leaking on failure by clearing all 
probe_trace_events

Wang Nan (1):
      perf probe: Clear probe_trace_event when add_probe_trace_event() fails


 tools/Makefile                 | 11 ++++++++++-
 tools/perf/builtin-inject.c    |  1 +
 tools/perf/builtin-report.c    |  6 +++---
 tools/perf/ui/browsers/hists.c |  7 +------
 tools/perf/util/build-id.c     |  1 +
 tools/perf/util/dso.c          | 17 +++++++++++++++++
 tools/perf/util/dso.h          |  1 +
 tools/perf/util/machine.c      |  1 +
 tools/perf/util/probe-finder.c | 24 +++++++++++++++++-------
 tools/perf/util/symbol.c       | 34 ++++++++++++++++------------------
 tools/perf/util/symbol.h       |  1 +
 11 files changed, 69 insertions(+), 35 deletions(-)

diff --git a/tools/Makefile b/tools/Makefile
index d6f307dfb1a3..7dc820a8c1f1 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 0a945d2e8ca5..99d127fe9c35 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 2853ad2bd435..f256fac1e722 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 e5afb8936040..fa9eb92c9e24 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 d909459fb54c..217b5a60e2ab 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 7c0c08386a1d..425df5c86c9c 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 fc8db9c764ac..45ec4d0a50ed 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 5ef90be2a249..8b303ff20289 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 bd8f03de5e40..05012bb178d7 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 b4cc7662677e..cd08027a6d2c 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 40073c60b83d..dcd786e364f2 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,
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to