Skip to content

Commit f1feb43

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 a80343f commit f1feb43

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
@@ -224,6 +224,21 @@ static int debugfs_create_trace_filter(struct snd_sof_dev *sdev)
224224
return 0;
225225
}
226226

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

337352
/* avoid duplicate traces at next open */
338353
if (sdev->dtrace_state != SOF_DTRACE_ENABLED)
339-
sdev->host_offset = 0;
354+
sof_dtrace_set_host_offset(sdev, 0);
340355

341356
return 0;
342357
}
@@ -408,7 +423,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev)
408423
params.buffer.pages = sdev->dma_trace_pages;
409424
params.stream_tag = 0;
410425

411-
sdev->host_offset = 0;
426+
sof_dtrace_set_host_offset(sdev, 0);
412427
sdev->dtrace_draining = false;
413428

414429
ret = snd_sof_dma_trace_init(sdev, &params);
@@ -506,10 +521,9 @@ int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev,
506521
if (!sdev->fw_trace_is_supported)
507522
return 0;
508523

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

515529
if (posn->overflow != 0)

0 commit comments

Comments
 (0)