On Mon, Nov 02, 2026 at 12:15:18PM +0000, James Clark wrote:
[...]
@@ -2215,6 +2209,29 @@ static int cs_etm__get_data_block(struct cs_etm_queue *etmq) */ cs_etm__flush_all_stack(etmq);
- /*
* Per-thread mode still uses a queue for each CPU, but that CPU can run* different threads. When the TID from the AUX record on a CPU changes,* re-initialize the thread using the AUX record/buffer fragment TID so* we can start decoding even if the context ID packet was cropped or* they're disabled.*/- if (etm->per_thread_decoding) {
struct cs_etm_traceid_queue *tidq = cs_etm__etmq_get_traceid_queue(etmq,CS_ETM_PER_THREAD_TRACEID);if (thread__tid(tidq->decode_thread) != etmq->buffer->tid) {thread__zput(tidq->frontend_thread);thread__zput(tidq->decode_thread);tidq->frontend_thread = machine__findnew_thread(&etm->session->machines.host, -1,etmq->buffer->tid);tidq->decode_thread = machine__findnew_thread(&etm->session->machines.host, -1,etmq->buffer->tid);}- }
Why not use PERF_RECORD_AUX events as an opportunity to update threads, similar to how we handle PERF_RECORD_SWITCH_CPU_WIDE?
- return 1;
} @@ -3288,7 +3305,9 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o if (aux_offset >= auxtrace_event->offset && aux_offset + aux_size <= auxtrace_event->offset + auxtrace_event->size) {
struct cs_etm_queue *etmq = cs_etm__get_queue(etm, auxtrace_event->cpu);
/* Old per-thread files have no CPU (before v6.4) */int queue_idx = sample->cpu == (u32)-1 ? 0 : sample->cpu;struct cs_etm_queue *etmq = cs_etm__get_queue(etm, queue_idx);
For per-thread mode, auxtrace_event->cpu is -1. So this is why we resort sample->cpu to retrieve CPU ID. This makes sense to me.