1

perf hist: Correct hist_entry->mem_info refcounts

The 'struct mem_info' is created by iter_prepare_mem_entry() at the
beginning and destroyed by iter_finish_mem_entry() at the end.

So if it's used in a new hist_entry, it should be cloned.

Simplify (hopefully) the logic by adding some helper functions and by
not holding the refcount in the temporary entry.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: https://lore.kernel.org/r/20240731235505.710436-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Namhyung Kim 2024-07-31 16:55:00 -07:00 committed by Arnaldo Carvalho de Melo
parent 7c5dd51bbb
commit 96465e0179
5 changed files with 42 additions and 7 deletions

View File

@ -476,6 +476,12 @@ static int hist_entry__init(struct hist_entry *he,
he->branch_info->to.ms.map = map__get(he->branch_info->to.ms.map);
}
if (he->mem_info) {
he->mem_info = mem_info__clone(template->mem_info);
if (he->mem_info == NULL)
goto err_infos;
}
if (hist_entry__has_callchains(he) && symbol_conf.use_callchain)
callchain_init(he->callchain);
@ -620,12 +626,6 @@ static struct hist_entry *hists__findnew_entry(struct hists *hists,
if (symbol_conf.cumulate_callchain)
he_stat__add_period(he->stat_acc, period);
/*
* This mem info was allocated from sample__resolve_mem
* and will not be used anymore.
*/
mem_info__zput(entry->mem_info);
block_info__delete(entry->block_info);
kvm_info__zput(entry->kvm_info);
@ -739,7 +739,7 @@ __hists__add_entry(struct hists *hists,
.filtered = symbol__parent_filter(sym_parent) | al->filtered,
.hists = hists,
.branch_info = bi,
.mem_info = mem_info__get(mi),
.mem_info = mi,
.kvm_info = ki,
.block_info = block_info,
.transaction = sample->transaction,

View File

@ -13,3 +13,21 @@ void addr_map_symbol__exit(struct addr_map_symbol *ams)
{
map_symbol__exit(&ams->ms);
}
void map_symbol__copy(struct map_symbol *dst, struct map_symbol *src)
{
dst->maps = maps__get(src->maps);
dst->map = map__get(src->map);
dst->sym = src->sym;
}
void addr_map_symbol__copy(struct addr_map_symbol *dst, struct addr_map_symbol *src)
{
map_symbol__copy(&dst->ms, &src->ms);
dst->addr = src->addr;
dst->al_addr = src->al_addr;
dst->al_level = src->al_level;
dst->phys_addr = src->phys_addr;
dst->data_page_size = src->data_page_size;
}

View File

@ -26,4 +26,7 @@ struct addr_map_symbol {
void map_symbol__exit(struct map_symbol *ms);
void addr_map_symbol__exit(struct addr_map_symbol *ams);
void map_symbol__copy(struct map_symbol *dst, struct map_symbol *src);
void addr_map_symbol__copy(struct addr_map_symbol *dst, struct addr_map_symbol *src);
#endif // __PERF_MAP_SYMBOL

View File

@ -33,3 +33,16 @@ struct mem_info *mem_info__new(void)
return result;
}
struct mem_info *mem_info__clone(struct mem_info *mi)
{
struct mem_info *result = mem_info__new();
if (result) {
addr_map_symbol__copy(mem_info__iaddr(result), mem_info__iaddr(mi));
addr_map_symbol__copy(mem_info__daddr(result), mem_info__daddr(mi));
mem_info__data_src(result)->val = mem_info__data_src(mi)->val;
}
return result;
}

View File

@ -15,6 +15,7 @@ DECLARE_RC_STRUCT(mem_info) {
};
struct mem_info *mem_info__new(void);
struct mem_info *mem_info__clone(struct mem_info *mi);
struct mem_info *mem_info__get(struct mem_info *mi);
void mem_info__put(struct mem_info *mi);