@@ -499,6 +499,29 @@ static enum trbe_fault_action trbe_get_fault_act(u64 trbsr)
499
499
return TRBE_FAULT_ACT_SPURIOUS ;
500
500
}
501
501
502
+ static unsigned long trbe_get_trace_size (struct perf_output_handle * handle ,
503
+ struct trbe_buf * buf , bool wrap )
504
+ {
505
+ u64 write ;
506
+ u64 start_off , end_off ;
507
+
508
+ /*
509
+ * If the TRBE has wrapped around the write pointer has
510
+ * wrapped and should be treated as limit.
511
+ */
512
+ if (wrap )
513
+ write = get_trbe_limit_pointer ();
514
+ else
515
+ write = get_trbe_write_pointer ();
516
+
517
+ end_off = write - get_trbe_base_pointer ();
518
+ start_off = PERF_IDX2OFF (handle -> head , buf );
519
+
520
+ if (WARN_ON_ONCE (end_off < start_off ))
521
+ return 0 ;
522
+ return (end_off - start_off );
523
+ }
524
+
502
525
static void * arm_trbe_alloc_buffer (struct coresight_device * csdev ,
503
526
struct perf_event * event , void * * pages ,
504
527
int nr_pages , bool snapshot )
@@ -560,9 +583,9 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
560
583
struct trbe_cpudata * cpudata = dev_get_drvdata (& csdev -> dev );
561
584
struct trbe_buf * buf = config ;
562
585
enum trbe_fault_action act ;
563
- unsigned long size , offset ;
564
- unsigned long write , base , status ;
586
+ unsigned long size , status ;
565
587
unsigned long flags ;
588
+ bool wrap = false;
566
589
567
590
WARN_ON (buf -> cpudata != cpudata );
568
591
WARN_ON (cpudata -> cpu != smp_processor_id ());
@@ -602,8 +625,6 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
602
625
* handle gets freed in etm_event_stop().
603
626
*/
604
627
trbe_drain_and_disable_local ();
605
- write = get_trbe_write_pointer ();
606
- base = get_trbe_base_pointer ();
607
628
608
629
/* Check if there is a pending interrupt and handle it here */
609
630
status = read_sysreg_s (SYS_TRBSR_EL1 );
@@ -627,20 +648,11 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
627
648
goto done ;
628
649
}
629
650
630
- /*
631
- * Otherwise, the buffer is full and the write pointer
632
- * has reached base. Adjust this back to the Limit pointer
633
- * for correct size. Also, mark the buffer truncated.
634
- */
635
- write = get_trbe_limit_pointer ();
636
651
trbe_report_wrap_event (handle );
652
+ wrap = true;
637
653
}
638
654
639
- offset = write - base ;
640
- if (WARN_ON_ONCE (offset < PERF_IDX2OFF (handle -> head , buf )))
641
- size = 0 ;
642
- else
643
- size = offset - PERF_IDX2OFF (handle -> head , buf );
655
+ size = trbe_get_trace_size (handle , buf , wrap );
644
656
645
657
done :
646
658
local_irq_restore (flags );
@@ -721,11 +733,10 @@ static int trbe_handle_overflow(struct perf_output_handle *handle)
721
733
{
722
734
struct perf_event * event = handle -> event ;
723
735
struct trbe_buf * buf = etm_perf_sink_config (handle );
724
- unsigned long offset , size ;
736
+ unsigned long size ;
725
737
struct etm_event_data * event_data ;
726
738
727
- offset = get_trbe_limit_pointer () - get_trbe_base_pointer ();
728
- size = offset - PERF_IDX2OFF (handle -> head , buf );
739
+ size = trbe_get_trace_size (handle , buf , true);
729
740
if (buf -> snapshot )
730
741
handle -> head += size ;
731
742
0 commit comments