Skip to content

Commit 3e55daf

Browse files
committed
ASoC: SOF: ipc3-dtrace: Add helper function to update the sdev->host_offset
We are using the READ_ONCE() on the debugfs read path for accessing sdev->host_offset, but the set is not atomic or protected in any way. Add a small helper to do the host_offset update and be really paranoid about the a possible race in update Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent 5a81ef7 commit 3e55daf

1 file changed

Lines changed: 20 additions & 6 deletions

File tree

sound/soc/sof/ipc3-dtrace.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,21 @@ static int debugfs_create_trace_filter(struct snd_sof_dev *sdev)
225225
return 0;
226226
}
227227

228+
static bool sof_dtrace_set_host_offset(struct snd_sof_dev *sdev, u32 new_offset)
229+
{
230+
u32 host_offset = READ_ONCE(sdev->host_offset);
231+
232+
if (host_offset != new_offset) {
233+
/* This is a bit paranoid and unlikely that it is needed */
234+
u32 ret = cmpxchg(&sdev->host_offset, host_offset, new_offset);
235+
236+
if (ret == host_offset)
237+
return true;
238+
}
239+
240+
return false;
241+
}
242+
228243
static size_t sof_dtrace_avail(struct snd_sof_dev *sdev,
229244
loff_t pos, size_t buffer_size)
230245
{
@@ -337,7 +352,7 @@ static int dfsentry_dtrace_release(struct inode *inode, struct file *file)
337352

338353
/* avoid duplicate traces at next open */
339354
if (sdev->dtrace_state != SOF_DTRACE_ENABLED)
340-
sdev->host_offset = 0;
355+
sof_dtrace_set_host_offset(sdev, 0);
341356

342357
return 0;
343358
}
@@ -409,7 +424,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev)
409424
params.buffer.pages = sdev->dma_trace_pages;
410425
params.stream_tag = 0;
411426

412-
sdev->host_offset = 0;
427+
sof_dtrace_set_host_offset(sdev, 0);
413428
sdev->dtrace_draining = false;
414429

415430
ret = snd_sof_dma_trace_init(sdev, &params);
@@ -507,10 +522,9 @@ int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev,
507522
if (!sdev->fw_trace_is_supported)
508523
return 0;
509524

510-
if (sdev->dtrace_state == SOF_DTRACE_ENABLED &&
511-
sdev->host_offset != posn->host_offset) {
512-
sdev->host_offset = posn->host_offset;
513-
wake_up(&sdev->trace_sleep);
525+
if (sdev->dtrace_state == SOF_DTRACE_ENABLED) {
526+
if (sof_dtrace_set_host_offset(sdev, posn->host_offset))
527+
wake_up(&sdev->trace_sleep);
514528
}
515529

516530
if (posn->overflow != 0)

0 commit comments

Comments
 (0)