Perf clears the IP of a user-only PMU sample when its interrupt skids into the kernel. The timestamp and TID remain valid, but the zero-IP check prevents --itrace=L from attaching decoded branch history.
Remove the IP check and keep matching samples to trace by time and thread.
Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan leo.yan@arm.com --- tools/perf/util/cs-etm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 00407a80933e1c0b76260aed5894dece50b9aecd..baa962085dba5226d9729a0ee8039374d5fcb1a0 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -3097,6 +3097,8 @@ static int cs_etm__br_stack_init(struct cs_etm_auxtrace *etm, /* * Add decoded branch history to an existing sample. The sample keeps its own * ip, callchain and event identity; only an absent branch stack is filled in. + * A user-only PMU sample can have a zero IP when the interrupt skids into + * the kernel; its thread and trace window still identify valid history. */ static int cs_etm__process_sample(struct cs_etm_auxtrace *etm, struct perf_session *session, @@ -3107,7 +3109,7 @@ static int cs_etm__process_sample(struct cs_etm_auxtrace *etm, int err;
if (!etm->synth_opts.add_last_branch || sample->branch_stack || - !sample->ip || !sample->time || sample->time == (u64)-1) + !sample->time || sample->time == (u64)-1) return 0;
/* Adding branch history to existing samples supports the host only */