mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 11:19:37 +00:00
coresight: Properly address concurrency in sink::update() functions
When operating in CPU-wide trace scenarios and working with an N:1 source/sink HW topology, update() functions need to be made atomic in order to avoid racing with start and stop operations. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Tested-by: Leo Yan <leo.yan@linaro.org> Tested-by: Robert Walker <robert.walker@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
12dfc9e022
commit
0916447c87
2 changed files with 6 additions and 2 deletions
|
@ -405,7 +405,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
|
|||
const u32 *barrier;
|
||||
u32 read_ptr, write_ptr, capacity;
|
||||
u32 status, read_data;
|
||||
unsigned long offset, to_read;
|
||||
unsigned long offset, to_read, flags;
|
||||
struct cs_buffers *buf = sink_config;
|
||||
struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
|
||||
|
||||
|
@ -414,6 +414,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
|
|||
|
||||
capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;
|
||||
|
||||
spin_lock_irqsave(&drvdata->spinlock, flags);
|
||||
__etb_disable_hw(drvdata);
|
||||
CS_UNLOCK(drvdata->base);
|
||||
|
||||
|
@ -524,6 +525,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
|
|||
}
|
||||
__etb_enable_hw(drvdata);
|
||||
CS_LOCK(drvdata->base);
|
||||
spin_unlock_irqrestore(&drvdata->spinlock, flags);
|
||||
|
||||
return to_read;
|
||||
}
|
||||
|
|
|
@ -413,7 +413,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
|
|||
u32 *buf_ptr;
|
||||
u64 read_ptr, write_ptr;
|
||||
u32 status;
|
||||
unsigned long offset, to_read;
|
||||
unsigned long offset, to_read, flags;
|
||||
struct cs_buffers *buf = sink_config;
|
||||
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
|
||||
|
||||
|
@ -424,6 +424,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
|
|||
if (WARN_ON_ONCE(drvdata->mode != CS_MODE_PERF))
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&drvdata->spinlock, flags);
|
||||
CS_UNLOCK(drvdata->base);
|
||||
|
||||
tmc_flush_and_stop(drvdata);
|
||||
|
@ -517,6 +518,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
|
|||
to_read = buf->nr_pages << PAGE_SHIFT;
|
||||
}
|
||||
CS_LOCK(drvdata->base);
|
||||
spin_unlock_irqrestore(&drvdata->spinlock, flags);
|
||||
|
||||
return to_read;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue