lkml.org 
[lkml]   [2021]   [Jul]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 06/10] coresight: trbe: Fix handling of spurious interrupts
    Date
    On a spurious IRQ, right now we disable the TRBE and then re-enable
    it back, resetting the "buffer" pointers(i.e BASE, LIMIT and more
    importantly WRITE) to the original pointers from the AUX handle.
    This implies that we overwrite any trace that was written so far,
    (by overwriting TRBPTR) while we should have ignored the IRQ.

    This patch cleans the behavior, by only stopping the TRBE if the
    IRQ was indeed raised, as we can read the TRBSR without stopping
    the TRBE (Only writes to the TRBSR requires the TRBE disabled).
    And also, on detecting a spurious IRQ after examining the TRBSR,
    we simply re-enable the TRBE without touching the other parameters.

    Cc: Anshuman Khandual <anshuman.khandual@arm.com>
    Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
    Cc: Mike Leach <mike.leach@linaro.org>
    Cc: Leo Yan <leo.yan@linaro.org>
    Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
    ---
    drivers/hwtracing/coresight/coresight-trbe.c | 29 ++++++++++----------
    1 file changed, 15 insertions(+), 14 deletions(-)

    diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
    index 62e1a08f73ff..503bea0137ae 100644
    --- a/drivers/hwtracing/coresight/coresight-trbe.c
    +++ b/drivers/hwtracing/coresight/coresight-trbe.c
    @@ -679,15 +679,16 @@ static int arm_trbe_disable(struct coresight_device *csdev)

    static void trbe_handle_spurious(struct perf_output_handle *handle)
    {
    - struct trbe_buf *buf = etm_perf_sink_config(handle);
    + u64 limitr = read_sysreg_s(SYS_TRBLIMITR_EL1);

    - buf->trbe_limit = compute_trbe_buffer_limit(handle);
    - buf->trbe_write = buf->trbe_base + PERF_IDX2OFF(handle->head, buf);
    - if (buf->trbe_limit == buf->trbe_base) {
    - trbe_drain_and_disable_local();
    - return;
    - }
    - trbe_enable_hw(buf);
    + /*
    + * If the IRQ was spurious, simply re-enable the TRBE
    + * back without modifiying the buffer parameters to
    + * retain the trace collected so far.
    + */
    + limitr |= TRBLIMITR_ENABLE;
    + write_sysreg_s(limitr, SYS_TRBLIMITR_EL1);
    + isb();
    }

    static void trbe_handle_overflow(struct perf_output_handle *handle)
    @@ -760,12 +761,7 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
    enum trbe_fault_action act;
    u64 status;

    - /*
    - * Ensure the trace is visible to the CPUs and
    - * any external aborts have been resolved.
    - */
    - trbe_drain_and_disable_local();
    -
    + /* Reads to TRBSR_EL1 is fine when TRBE is active */
    status = read_sysreg_s(SYS_TRBSR_EL1);
    /*
    * If the pending IRQ was handled by update_buffer callback
    @@ -774,6 +770,11 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
    if (!is_trbe_irq(status))
    return IRQ_NONE;

    + /*
    + * Ensure the trace is visible to the CPUs and
    + * any external aborts have been resolved.
    + */
    + trbe_drain_and_disable_local();
    clr_trbe_irq();
    isb();

    --
    2.24.1
    \
     
     \ /
      Last update: 2021-07-23 14:47    [W:4.056 / U:0.116 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site