coresight: trbe: Add a helper to calculate the trace generated
authorSuzuki K Poulose <suzuki.poulose@arm.com>
Tue, 19 Oct 2021 16:31:43 +0000 (17:31 +0100)
committerMathieu Poirier <mathieu.poirier@linaro.org>
Wed, 27 Oct 2021 17:45:46 +0000 (11:45 -0600)
We collect the trace from the TRBE on FILL event from IRQ context
and via update_buffer(), when the event is stopped. Let us
consolidate how we calculate the trace generated into a helper.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20211019163153.3692640-6-suzuki.poulose@arm.com
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
drivers/hwtracing/coresight/coresight-trbe.c

index 5d77baba8b0fc1912368d3f8753d12a4d9bca8b5..54f5d61ee9fb83f3cbe3b5e450aed4a1f7c1a0e6 100644 (file)
@@ -499,6 +499,29 @@ static enum trbe_fault_action trbe_get_fault_act(u64 trbsr)
        return TRBE_FAULT_ACT_SPURIOUS;
 }
 
+static unsigned long trbe_get_trace_size(struct perf_output_handle *handle,
+                                        struct trbe_buf *buf, bool wrap)
+{
+       u64 write;
+       u64 start_off, end_off;
+
+       /*
+        * If the TRBE has wrapped around the write pointer has
+        * wrapped and should be treated as limit.
+        */
+       if (wrap)
+               write = get_trbe_limit_pointer();
+       else
+               write = get_trbe_write_pointer();
+
+       end_off = write - get_trbe_base_pointer();
+       start_off = PERF_IDX2OFF(handle->head, buf);
+
+       if (WARN_ON_ONCE(end_off < start_off))
+               return 0;
+       return (end_off - start_off);
+}
+
 static void *arm_trbe_alloc_buffer(struct coresight_device *csdev,
                                   struct perf_event *event, void **pages,
                                   int nr_pages, bool snapshot)
@@ -560,9 +583,9 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
        struct trbe_cpudata *cpudata = dev_get_drvdata(&csdev->dev);
        struct trbe_buf *buf = config;
        enum trbe_fault_action act;
-       unsigned long size, offset;
-       unsigned long write, base, status;
+       unsigned long size, status;
        unsigned long flags;
+       bool wrap = false;
 
        WARN_ON(buf->cpudata != cpudata);
        WARN_ON(cpudata->cpu != smp_processor_id());
@@ -602,8 +625,6 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
         * handle gets freed in etm_event_stop().
         */
        trbe_drain_and_disable_local();
-       write = get_trbe_write_pointer();
-       base = get_trbe_base_pointer();
 
        /* Check if there is a pending interrupt and handle it here */
        status = read_sysreg_s(SYS_TRBSR_EL1);
@@ -627,20 +648,11 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
                        goto done;
                }
 
-               /*
-                * Otherwise, the buffer is full and the write pointer
-                * has reached base. Adjust this back to the Limit pointer
-                * for correct size. Also, mark the buffer truncated.
-                */
-               write = get_trbe_limit_pointer();
                trbe_report_wrap_event(handle);
+               wrap = true;
        }
 
-       offset = write - base;
-       if (WARN_ON_ONCE(offset < PERF_IDX2OFF(handle->head, buf)))
-               size = 0;
-       else
-               size = offset - PERF_IDX2OFF(handle->head, buf);
+       size = trbe_get_trace_size(handle, buf, wrap);
 
 done:
        local_irq_restore(flags);
@@ -721,11 +733,10 @@ static int trbe_handle_overflow(struct perf_output_handle *handle)
 {
        struct perf_event *event = handle->event;
        struct trbe_buf *buf = etm_perf_sink_config(handle);
-       unsigned long offset, size;
+       unsigned long size;
        struct etm_event_data *event_data;
 
-       offset = get_trbe_limit_pointer() - get_trbe_base_pointer();
-       size = offset - PERF_IDX2OFF(handle->head, buf);
+       size = trbe_get_trace_size(handle, buf, true);
        if (buf->snapshot)
                handle->head += size;