diff options
author | Namhyung Kim <namhyung@kernel.org> | 2015-12-10 02:53:20 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-12-10 13:56:58 -0500 |
commit | 61fa0e94ca6ab62db5e095a5528150bf9962196d (patch) | |
tree | fcd801b91e0142e83910dee61503bdc678767765 /tools/perf | |
parent | 3f86eb6b0771d785099c91354838d3f8d8126630 (diff) |
perf top: Delete half-processed hist entries when exit
After sample processing is done, hist entries are in both of
hists->entries and hists->entries_in (or hists->entries_collapsed). So
I guess perf report does not have leaks on hists.
But for perf top, it's possible to have half-processed entries which are
only in hists->entries_in. Eventually they will go to the
hists->entries and get freed but they cannot be deleted by current
hists__delete_entries(). This patch adds hists__delete_all_entries
function to delete those entries.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-and-Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1449734015-9148-2-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/util/hist.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 565ea3549894..56e97f5af598 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -270,6 +270,8 @@ static void hists__delete_entry(struct hists *hists, struct hist_entry *he) | |||
270 | 270 | ||
271 | if (sort__need_collapse) | 271 | if (sort__need_collapse) |
272 | rb_erase(&he->rb_node_in, &hists->entries_collapsed); | 272 | rb_erase(&he->rb_node_in, &hists->entries_collapsed); |
273 | else | ||
274 | rb_erase(&he->rb_node_in, hists->entries_in); | ||
273 | 275 | ||
274 | --hists->nr_entries; | 276 | --hists->nr_entries; |
275 | if (!he->filtered) | 277 | if (!he->filtered) |
@@ -1567,11 +1569,33 @@ static int hists_evsel__init(struct perf_evsel *evsel) | |||
1567 | return 0; | 1569 | return 0; |
1568 | } | 1570 | } |
1569 | 1571 | ||
1572 | static void hists__delete_remaining_entries(struct rb_root *root) | ||
1573 | { | ||
1574 | struct rb_node *node; | ||
1575 | struct hist_entry *he; | ||
1576 | |||
1577 | while (!RB_EMPTY_ROOT(root)) { | ||
1578 | node = rb_first(root); | ||
1579 | rb_erase(node, root); | ||
1580 | |||
1581 | he = rb_entry(node, struct hist_entry, rb_node_in); | ||
1582 | hist_entry__delete(he); | ||
1583 | } | ||
1584 | } | ||
1585 | |||
1586 | static void hists__delete_all_entries(struct hists *hists) | ||
1587 | { | ||
1588 | hists__delete_entries(hists); | ||
1589 | hists__delete_remaining_entries(&hists->entries_in_array[0]); | ||
1590 | hists__delete_remaining_entries(&hists->entries_in_array[1]); | ||
1591 | hists__delete_remaining_entries(&hists->entries_collapsed); | ||
1592 | } | ||
1593 | |||
1570 | static void hists_evsel__exit(struct perf_evsel *evsel) | 1594 | static void hists_evsel__exit(struct perf_evsel *evsel) |
1571 | { | 1595 | { |
1572 | struct hists *hists = evsel__hists(evsel); | 1596 | struct hists *hists = evsel__hists(evsel); |
1573 | 1597 | ||
1574 | hists__delete_entries(hists); | 1598 | hists__delete_all_entries(hists); |
1575 | } | 1599 | } |
1576 | 1600 | ||
1577 | /* | 1601 | /* |