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;