@@ -71,6 +71,7 @@ struct arm_spe {
71
71
u64 kernel_start ;
72
72
73
73
unsigned long num_events ;
74
+ u8 use_ctx_pkt_for_pid ;
74
75
};
75
76
76
77
struct arm_spe_queue {
@@ -226,6 +227,44 @@ static inline u8 arm_spe_cpumode(struct arm_spe *spe, u64 ip)
226
227
PERF_RECORD_MISC_USER ;
227
228
}
228
229
230
+ static void arm_spe_set_pid_tid_cpu (struct arm_spe * spe ,
231
+ struct auxtrace_queue * queue )
232
+ {
233
+ struct arm_spe_queue * speq = queue -> priv ;
234
+ pid_t tid ;
235
+
236
+ tid = machine__get_current_tid (spe -> machine , speq -> cpu );
237
+ if (tid != -1 ) {
238
+ speq -> tid = tid ;
239
+ thread__zput (speq -> thread );
240
+ } else
241
+ speq -> tid = queue -> tid ;
242
+
243
+ if ((!speq -> thread ) && (speq -> tid != -1 )) {
244
+ speq -> thread = machine__find_thread (spe -> machine , -1 ,
245
+ speq -> tid );
246
+ }
247
+
248
+ if (speq -> thread ) {
249
+ speq -> pid = speq -> thread -> pid_ ;
250
+ if (queue -> cpu == -1 )
251
+ speq -> cpu = speq -> thread -> cpu ;
252
+ }
253
+ }
254
+
255
+ static int arm_spe_set_tid (struct arm_spe_queue * speq , pid_t tid )
256
+ {
257
+ struct arm_spe * spe = speq -> spe ;
258
+ int err = machine__set_current_tid (spe -> machine , speq -> cpu , -1 , tid );
259
+
260
+ if (err )
261
+ return err ;
262
+
263
+ arm_spe_set_pid_tid_cpu (spe , & spe -> queues .queue_array [speq -> queue_nr ]);
264
+
265
+ return 0 ;
266
+ }
267
+
229
268
static void arm_spe_prep_sample (struct arm_spe * spe ,
230
269
struct arm_spe_queue * speq ,
231
270
union perf_event * event ,
@@ -460,6 +499,19 @@ static int arm_spe_run_decoder(struct arm_spe_queue *speq, u64 *timestamp)
460
499
* can correlate samples between Arm SPE trace data and other
461
500
* perf events with correct time ordering.
462
501
*/
502
+
503
+ /*
504
+ * Update pid/tid info.
505
+ */
506
+ record = & speq -> decoder -> record ;
507
+ if (!spe -> timeless_decoding && record -> context_id != (u64 )- 1 ) {
508
+ ret = arm_spe_set_tid (speq , record -> context_id );
509
+ if (ret )
510
+ return ret ;
511
+
512
+ spe -> use_ctx_pkt_for_pid = true;
513
+ }
514
+
463
515
ret = arm_spe_sample (speq );
464
516
if (ret )
465
517
return ret ;
@@ -586,31 +638,6 @@ static bool arm_spe__is_timeless_decoding(struct arm_spe *spe)
586
638
return timeless_decoding ;
587
639
}
588
640
589
- static void arm_spe_set_pid_tid_cpu (struct arm_spe * spe ,
590
- struct auxtrace_queue * queue )
591
- {
592
- struct arm_spe_queue * speq = queue -> priv ;
593
- pid_t tid ;
594
-
595
- tid = machine__get_current_tid (spe -> machine , speq -> cpu );
596
- if (tid != -1 ) {
597
- speq -> tid = tid ;
598
- thread__zput (speq -> thread );
599
- } else
600
- speq -> tid = queue -> tid ;
601
-
602
- if ((!speq -> thread ) && (speq -> tid != -1 )) {
603
- speq -> thread = machine__find_thread (spe -> machine , -1 ,
604
- speq -> tid );
605
- }
606
-
607
- if (speq -> thread ) {
608
- speq -> pid = speq -> thread -> pid_ ;
609
- if (queue -> cpu == -1 )
610
- speq -> cpu = speq -> thread -> cpu ;
611
- }
612
- }
613
-
614
641
static int arm_spe_process_queues (struct arm_spe * spe , u64 timestamp )
615
642
{
616
643
unsigned int queue_nr ;
@@ -641,7 +668,12 @@ static int arm_spe_process_queues(struct arm_spe *spe, u64 timestamp)
641
668
ts = timestamp ;
642
669
}
643
670
644
- arm_spe_set_pid_tid_cpu (spe , queue );
671
+ /*
672
+ * A previous context-switch event has set pid/tid in the machine's context, so
673
+ * here we need to update the pid/tid in the thread and SPE queue.
674
+ */
675
+ if (!spe -> use_ctx_pkt_for_pid )
676
+ arm_spe_set_pid_tid_cpu (spe , queue );
645
677
646
678
ret = arm_spe_run_decoder (speq , & ts );
647
679
if (ret < 0 ) {
@@ -740,8 +772,9 @@ static int arm_spe_process_event(struct perf_session *session,
740
772
if (err )
741
773
return err ;
742
774
743
- if (event -> header .type == PERF_RECORD_SWITCH_CPU_WIDE ||
744
- event -> header .type == PERF_RECORD_SWITCH )
775
+ if (!spe -> use_ctx_pkt_for_pid &&
776
+ (event -> header .type == PERF_RECORD_SWITCH_CPU_WIDE ||
777
+ event -> header .type == PERF_RECORD_SWITCH ))
745
778
err = arm_spe_context_switch (spe , event , sample );
746
779
}
747
780
@@ -808,7 +841,15 @@ static int arm_spe_flush(struct perf_session *session __maybe_unused,
808
841
return arm_spe_process_timeless_queues (spe , -1 ,
809
842
MAX_TIMESTAMP - 1 );
810
843
811
- return arm_spe_process_queues (spe , MAX_TIMESTAMP );
844
+ ret = arm_spe_process_queues (spe , MAX_TIMESTAMP );
845
+ if (ret )
846
+ return ret ;
847
+
848
+ if (!spe -> use_ctx_pkt_for_pid )
849
+ ui__warning ("Arm SPE CONTEXT packets not found in the traces.\n"
850
+ "Matching of TIDs to SPE events could be inaccurate.\n" );
851
+
852
+ return 0 ;
812
853
}
813
854
814
855
static void arm_spe_free_queue (void * priv )
0 commit comments