[PATCH v7 1/8] perf cs-etm: Filter synthesized branch samples
James Clark
james.clark at linaro.org
Thu Jun 11 01:58:46 PDT 2026
On 11/06/2026 8:56 am, Leo Yan wrote:
> From: Leo Yan <leo.yan at linaro.org>
>
> The itrace 'c' and 'r' options request synthesized branch events for
> calls and returns only. For perf script the default itrace options are
> "--itrace=ce", so CS ETM should emit call branches and error events by
> default.
You need to update test_arm_coresight_disasm.sh to pass --itrace=b for
both tests now because it needs every branch, not just calls. Should
probably update the documentation and examples in arm-cs-trace-disasm.py
too.
With that,
Reviewed-by: James Clark <james.clark at linaro.org>
>
> CS ETM currently synthesizes a branch sample for every decoded taken
> branch whenever branch synthesis is enabled. This produces redundant
> jump and conditional branch samples.
>
> Add a branch filter derived from the itrace calls and returns options.
> When neither option is set, keep the existing behavior and synthesize all
> branch samples. When calls or returns are requested, emit only branch
> samples whose flags match the selected branch type, while preserving trace
> begin/end markers.
>
> Before:
>
> perf script -F,+flags
>
> callchain_test 6114 [005] 331519.825214: 1 branches: tr strt jmp 0 [unknown] ([unknown]) => ffff8000803a3a68 perf_report_aux_output_id+0x50 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000803a3a74 perf_report_aux_output_id+0x5c ([kernel.kallsyms]) => ffff8000817f4d88 memset+0x0 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: jmp ffff8000817f4d8c memset+0x4 ([kernel.kallsyms]) => ffff8000817f4c00 __pi_memset_generic+0x0 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4c1c __pi_memset_generic+0x1c ([kernel.kallsyms]) => ffff8000817f4c44 __pi_memset_generic+0x44 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4c4c __pi_memset_generic+0x4c ([kernel.kallsyms]) => ffff8000817f4c5c __pi_memset_generic+0x5c ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4c5c __pi_memset_generic+0x5c ([kernel.kallsyms]) => ffff8000817f4cf0 __pi_memset_generic+0xf0 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4d30 __pi_memset_generic+0x130 ([kernel.kallsyms]) => ffff8000817f4d68 __pi_memset_generic+0x168 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4d78 __pi_memset_generic+0x178 ([kernel.kallsyms]) => ffff8000817f4d6c __pi_memset_generic+0x16c ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4d78 __pi_memset_generic+0x178 ([kernel.kallsyms]) => ffff8000817f4d6c __pi_memset_generic+0x16c ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4d78 __pi_memset_generic+0x178 ([kernel.kallsyms]) => ffff8000817f4d6c __pi_memset_generic+0x16c ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: return ffff8000817f4d84 __pi_memset_generic+0x184 ([kernel.kallsyms]) => ffff8000803a3a78 perf_report_aux_output_id+0x60 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000803a3a98 perf_report_aux_output_id+0x80 ([kernel.kallsyms]) => ffff8000803a3b04 perf_report_aux_output_id+0xec ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000803a3b1c perf_report_aux_output_id+0x104 ([kernel.kallsyms]) => ffff8000803a38f8 __perf_event_header__init_id+0x0 ([kernel.kallsyms])
>
> After:
>
> callchain_test 6114 [005] 331519.825214: 1 branches: tr strt jmp 0 [unknown] ([unknown]) => ffff8000803a3a68 perf_report_aux_output_id+0x50 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000803a3a74 perf_report_aux_output_id+0x5c ([kernel.kallsyms]) => ffff8000817f4d88 memset+0x0 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000803a3b1c perf_report_aux_output_id+0x104 ([kernel.kallsyms]) => ffff8000803a38f8 __perf_event_header__init_id+0x0 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000803a39c0 __perf_event_header__init_id+0xc8 ([kernel.kallsyms]) => ffff800080105258 __task_pid_nr_ns+0x0 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: call ffff80008010528c __task_pid_nr_ns+0x34 ([kernel.kallsyms]) => ffff8000801d5610 __rcu_read_lock+0x0 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000801052b0 __task_pid_nr_ns+0x58 ([kernel.kallsyms]) => ffff800080192078 lock_acquire+0x0 ([kernel.kallsyms])
> callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000801923f4 lock_acquire+0x37c ([kernel.kallsyms]) => ffff8000801d6da0 rcu_is_watching+0x0 ([kernel.kallsyms])
>
> Fixes: b12235b113cf ("perf tools: Add mechanic to synthesise CoreSight trace packets")
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: Leo Yan <leo.yan at arm.com>
> ---
> tools/perf/util/cs-etm.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index 5e92359f51a7cb87a26866ae71466fcce809d551..c2b0f98ceee7671d0e98cfe5673c6f4ec19707a5 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -70,6 +70,7 @@ struct cs_etm_auxtrace {
> int num_cpu;
> u64 latest_kernel_timestamp;
> u32 auxtrace_type;
> + u32 branches_filter;
> u64 branches_sample_type;
> u64 branches_id;
> u64 instructions_sample_type;
> @@ -1681,6 +1682,10 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
> } dummy_bs;
> u64 ip;
>
> + if (etm->branches_filter &&
> + !(etm->branches_filter & tidq->prev_packet->flags))
> + return 0;
> +
> ip = cs_etm__last_executed_instr(tidq->prev_packet);
>
> event->sample.header.type = PERF_RECORD_SAMPLE;
> @@ -3517,6 +3522,16 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
> etm->synth_opts.callchain = false;
> }
>
> + if (etm->synth_opts.calls)
> + etm->branches_filter |= PERF_IP_FLAG_CALL |
> + PERF_IP_FLAG_TRACE_BEGIN |
> + PERF_IP_FLAG_TRACE_END;
> +
> + if (etm->synth_opts.returns)
> + etm->branches_filter |= PERF_IP_FLAG_RETURN |
> + PERF_IP_FLAG_TRACE_BEGIN |
> + PERF_IP_FLAG_TRACE_END;
> +
> etm->session = session;
>
> etm->num_cpu = num_cpu;
>
More information about the linux-arm-kernel
mailing list