On 04/11/2026 14:24, Leo Yan wrote:
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?
In cs_etm__queue_aux_fragment() we check if the TID from the AUX record is the same as the one on the buffer, so it doesn't make a difference. They're always the same:
if (auxtrace_event->tid != sample->tid) return 1;
We can't use it directly in cs_etm__process_event() because we're not decoding in order with Perf events yet. In my WIP JIT patches we do, but it still makes sense to continue to use the TID from the buffer because you don't always have timestamps available to update threads when the AUX event comes.
- 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.
Yes, and it's only set on AUX records since we started always doing this:
evsel__set_sample_bit(cs_etm_evsel, CPU);
Otherwise it was -1 there too, hence the condition for old files.