[PATCH 18/25] perf cs-etm: Unify timeless buffer decoding
From: Leo Yan <leo.yan@arm.com>
Date: 2026-09-15 15:50:47
Also in:
linux-doc, linux-perf-users, lkml
Subsystem:
arm/coresight framework and drivers, performance events subsystem, performance events tooling arm64, the rest · Maintainers:
Suzuki K Poulose, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Linus Torvalds
Per-thread and per-CPU timeless decoding use separate loops for the same buffer processing. Per-thread mode already collects packets in a single trace ID queue, so both modes can share the queue iteration. Use cs_etm__run_timeless_decoder() for both modes, keeping the thread selection in the caller. Propagate packet processing and end-of-block errors through the common decoding path. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan <leo.yan@arm.com> --- tools/perf/util/cs-etm.c | 68 ++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 52 deletions(-)
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index baa962085dba5226d9729a0ee8039374d5fcb1a0..1a53431161e995ba6b3cfdc86e338ed26e675774 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c@@ -2681,47 +2681,9 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq) } } -static int cs_etm__run_per_thread_timeless_decoder(struct cs_etm_queue *etmq) +static int cs_etm__run_timeless_decoder(struct cs_etm_queue *etmq) { - int err = 0; - struct cs_etm_traceid_queue *tidq; - - tidq = cs_etm__etmq_get_traceid_queue(etmq, CS_ETM_PER_THREAD_TRACEID); - if (!tidq) - return -EINVAL; - - /* Go through each buffer in the queue and decode them one by one */ - while (1) { - err = cs_etm__get_data_block(etmq); - if (err <= 0) - return err; - - /* Run trace decoder until buffer consumed or end of trace */ - do { - err = cs_etm__decode_data_block(etmq); - if (err) - return err; - - /* - * Process each packet in this chunk, nothing to do if - * an error occurs other than hoping the next one will - * be better. - */ - err = cs_etm__process_traceid_queue(etmq, tidq); - - } while (etmq->buf_len); - - if (err == 0) - /* Flush any remaining branch stack entries */ - err = cs_etm__end_block(etmq, tidq); - } - - return err; -} - -static int cs_etm__run_per_cpu_timeless_decoder(struct cs_etm_queue *etmq) -{ - int idx, err = 0; + int idx, err; struct cs_etm_traceid_queue *tidq; struct int_node *inode;
@@ -2731,23 +2693,23 @@ static int cs_etm__run_per_cpu_timeless_decoder(struct cs_etm_queue *etmq) if (err <= 0) return err; - /* Run trace decoder until buffer consumed or end of trace */ + /* Run trace decoder until the input buffer is consumed. */ do { err = cs_etm__decode_data_block(etmq); if (err) return err; /* - * cs_etm__run_per_thread_timeless_decoder() runs on a - * single traceID queue because each TID has a separate - * buffer. But here in per-cpu mode we need to iterate - * over each channel instead. + * Per-thread decoding uses a single traceID queue; + * formatted per-CPU buffers can contain several. */ intlist__for_each_entry(inode, etmq->traceid_queues_list) { idx = (int)(intptr_t)inode->priv; tidq = etmq->traceid_queues[idx]; - cs_etm__process_traceid_queue(etmq, tidq); + err = cs_etm__process_traceid_queue(etmq, tidq); + if (err) + return err; } } while (etmq->buf_len);
@@ -2760,8 +2722,6 @@ static int cs_etm__run_per_cpu_timeless_decoder(struct cs_etm_queue *etmq) return err; } } - - return err; } static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
@@ -2774,6 +2734,7 @@ static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm, struct auxtrace_queue *queue = &etm->queues.queue_array[i]; struct cs_etm_queue *etmq = queue->priv; struct cs_etm_traceid_queue *tidq; + int err; if (!etmq) continue;
@@ -2785,10 +2746,13 @@ static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm, if (!tidq) continue; - if (tid == -1 || thread__tid(tidq->frontend_thread) == tid) - cs_etm__run_per_thread_timeless_decoder(etmq); - } else - cs_etm__run_per_cpu_timeless_decoder(etmq); + if (tid != -1 && thread__tid(tidq->frontend_thread) != tid) + continue; + } + + err = cs_etm__run_timeless_decoder(etmq); + if (err) + return err; } return 0;
--
2.34.1