diff options
Diffstat (limited to 'tools/perf/util/hist.c')
-rw-r--r-- | tools/perf/util/hist.c | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 7ace7a10054d..f24fd1954f6c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 #include "callchain.h" -#include "util.h" #include "build-id.h" #include "hist.h" #include "map.h" @@ -20,6 +19,7 @@ #include <inttypes.h> #include <sys/param.h> #include <linux/time64.h> +#include <linux/zalloc.h> static bool hists__filter_entry_by_dso(struct hists *hists, struct hist_entry *he); @@ -376,6 +376,24 @@ void hists__delete_entries(struct hists *hists) } } +struct hist_entry *hists__get_entry(struct hists *hists, int idx) +{ + struct rb_node *next = rb_first_cached(&hists->entries); + struct hist_entry *n; + int i = 0; + + while (next) { + n = rb_entry(next, struct hist_entry, rb_node); + if (i == idx) + return n; + + next = rb_next(&n->rb_node); + i++; + } + + return NULL; +} + /* * histogram, sorted on item, collects periods */ @@ -454,16 +472,16 @@ static int hist_entry__init(struct hist_entry *he, return 0; err_srcline: - free(he->srcline); + zfree(&he->srcline); err_rawdata: - free(he->raw_data); + zfree(&he->raw_data); err_infos: if (he->branch_info) { map__put(he->branch_info->from.map); map__put(he->branch_info->to.map); - free(he->branch_info); + zfree(&he->branch_info); } if (he->mem_info) { map__put(he->mem_info->iaddr.map); @@ -471,7 +489,7 @@ err_infos: } err: map__zput(he->ms.map); - free(he->stat_acc); + zfree(&he->stat_acc); return -ENOMEM; } @@ -574,6 +592,8 @@ static struct hist_entry *hists__findnew_entry(struct hists *hists, */ mem_info__zput(entry->mem_info); + block_info__zput(entry->block_info); + /* If the map of an existing hist_entry has * become out-of-date due to an exec() or * similar, update it. Otherwise we will @@ -645,6 +665,7 @@ __hists__add_entry(struct hists *hists, struct symbol *sym_parent, struct branch_info *bi, struct mem_info *mi, + struct block_info *block_info, struct perf_sample *sample, bool sample_self, struct hist_entry_ops *ops) @@ -677,6 +698,7 @@ __hists__add_entry(struct hists *hists, .hists = hists, .branch_info = bi, .mem_info = mi, + .block_info = block_info, .transaction = sample->transaction, .raw_data = sample->raw_data, .raw_size = sample->raw_size, @@ -699,7 +721,7 @@ struct hist_entry *hists__add_entry(struct hists *hists, struct perf_sample *sample, bool sample_self) { - return __hists__add_entry(hists, al, sym_parent, bi, mi, + return __hists__add_entry(hists, al, sym_parent, bi, mi, NULL, sample, sample_self, NULL); } @@ -712,10 +734,22 @@ struct hist_entry *hists__add_entry_ops(struct hists *hists, struct perf_sample *sample, bool sample_self) { - return __hists__add_entry(hists, al, sym_parent, bi, mi, + return __hists__add_entry(hists, al, sym_parent, bi, mi, NULL, sample, sample_self, ops); } +struct hist_entry *hists__add_entry_block(struct hists *hists, + struct addr_location *al, + struct block_info *block_info) +{ + struct hist_entry entry = { + .block_info = block_info, + .hists = hists, + }, *he = hists__findnew_entry(hists, &entry, al, false); + + return he; +} + static int iter_next_nop_entry(struct hist_entry_iter *iter __maybe_unused, struct addr_location *al __maybe_unused) @@ -1213,14 +1247,17 @@ void hist_entry__delete(struct hist_entry *he) mem_info__zput(he->mem_info); } + if (he->block_info) + block_info__zput(he->block_info); + zfree(&he->res_samples); zfree(&he->stat_acc); free_srcline(he->srcline); if (he->srcfile && he->srcfile[0]) - free(he->srcfile); + zfree(&he->srcfile); free_callchain(he->callchain); - free(he->trace_output); - free(he->raw_data); + zfree(&he->trace_output); + zfree(&he->raw_data); ops->free(he); } @@ -2561,7 +2598,7 @@ int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool sh char unit; int printed; const struct dso *dso = hists->dso_filter; - const struct thread *thread = hists->thread_filter; + struct thread *thread = hists->thread_filter; int socket_id = hists->socket_filter; unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; u64 nr_events = hists->stats.total_period; @@ -2704,10 +2741,10 @@ static void hists_evsel__exit(struct perf_evsel *evsel) list_for_each_entry_safe(node, tmp, &hists->hpp_formats, list) { perf_hpp_list__for_each_format_safe(&node->hpp, fmt, pos) { - list_del(&fmt->list); + list_del_init(&fmt->list); free(fmt); } - list_del(&node->list); + list_del_init(&node->list); free(node); } } |