[PATCH 3/3] perf hist: Do not delete cumulative caller entries before stat_acc decays
From: Ian Rogers
Date: Mon Oct 26 2026 - 02:52:57 EST
When symbol_conf.cumulate_callchain is enabled (the default in
'perf top -g'), callchain parent/caller entries have he->stat.period == 0
and accumulate their period in he->stat_acc->period.
hists__decay_entry() decays both he->stat.period and he->stat_acc->period,
but only checks if he->stat.period == 0 as the return condition for
deleting the entry in hists__decay_entries(). As a result, every callchain
caller entry with 0 self-period is unconditionally deleted from the
histogram on the first decay pass, destroying its callchain tree while it
still has non-zero cumulative period.
Only mark an entry for deletion in hists__decay_entry() when both
he->stat.period == 0 and (when cumulate_callchain is active)
he->stat_acc->period == 0.
Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
---
tools/perf/util/hist.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 443694926f1a..e75a4fcce975 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -409,7 +409,8 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
u64 prev_period = he->stat.period;
u64 prev_latency = he->stat.latency;
- if (prev_period == 0)
+ if (prev_period == 0 &&
+ (!symbol_conf.cumulate_callchain || he->stat_acc->period == 0))
return true;
he_stat__decay(&he->stat);
@@ -442,7 +443,8 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
}
}
- return he->stat.period == 0 && he->stat.latency == 0;
+ return he->stat.period == 0 && he->stat.latency == 0 &&
+ (!symbol_conf.cumulate_callchain || he->stat_acc->period == 0);
}
static void hists__delete_entry(struct hists *hists, struct hist_entry *he)
--
2.56.0.307.g5fe7bd680c-goog