dma-trace: Fix potential race issue by using blocking DMA copy

It is possible that that in trace_work() sof_ipc_dma_trace_posn ipc
message reaches host side sof driver before the dma_copy_to_host_nowait()
is finished. Change the dma_copy_to_host_nowait() implementation to
dma_copy_to_host() by adding DMA_COPY_BLOCKING flag to dma_copy()
command.

The flag is already there on the !defined(CONFIG_DMA_GW) version of
the function and the old name of the function was a bit misleading.

This commit changes also probe.c probe_task() so that it also uses the
new blocking DMA copy. I could not see any justification to use nowait
version there either.

Signed-off-by: Jyri Sarha <jyri.sarha@intel.com>
This commit is contained in:
Jyri Sarha 2022-02-08 17:14:03 +02:00 committed by Liam Girdwood
parent 5afc494671
commit 443b21de4b
4 changed files with 15 additions and 15 deletions

View File

@ -541,8 +541,8 @@ int dma_copy_from_host_nowait(struct dma_copy *dc,
int32_t size);
/* DMA copy data from DSP to host */
int dma_copy_to_host_nowait(struct dma_copy *dc, struct dma_sg_config *host_sg,
int32_t host_offset, void *local_ptr, int32_t size);
int dma_copy_to_host(struct dma_copy *dc, struct dma_sg_config *host_sg,
int32_t host_offset, void *local_ptr, int32_t size);
int dma_copy_set_stream_tag(struct dma_copy *dc, uint32_t stream_tag);

View File

@ -59,13 +59,13 @@ static struct dma_sg_elem *sg_get_elem_at(struct dma_sg_config *host_sg,
*/
#if CONFIG_DMA_GW
int dma_copy_to_host_nowait(struct dma_copy *dc, struct dma_sg_config *host_sg,
int32_t host_offset, void *local_ptr, int32_t size)
int dma_copy_to_host(struct dma_copy *dc, struct dma_sg_config *host_sg,
int32_t host_offset, void *local_ptr, int32_t size)
{
int ret;
/* tell gateway to copy */
ret = dma_copy(dc->chan, size, 0);
ret = dma_copy(dc->chan, size, DMA_COPY_BLOCKING);
if (ret < 0)
return ret;
@ -75,8 +75,8 @@ int dma_copy_to_host_nowait(struct dma_copy *dc, struct dma_sg_config *host_sg,
#else /* CONFIG_DMA_GW */
int dma_copy_to_host_nowait(struct dma_copy *dc, struct dma_sg_config *host_sg,
int32_t host_offset, void *local_ptr, int32_t size)
int dma_copy_to_host(struct dma_copy *dc, struct dma_sg_config *host_sg,
int32_t host_offset, void *local_ptr, int32_t size)
{
struct dma_sg_config config;
struct dma_sg_elem *host_sg_elem;

View File

@ -201,15 +201,15 @@ static enum task_state probe_task(void *data)
int err;
if (_probe->ext_dma.dmapb.avail > 0)
err = dma_copy_to_host_nowait(&_probe->ext_dma.dc,
&_probe->ext_dma.config, 0,
(void *)_probe->ext_dma.dmapb.r_ptr,
_probe->ext_dma.dmapb.avail);
err = dma_copy_to_host(&_probe->ext_dma.dc,
&_probe->ext_dma.config, 0,
(void *)_probe->ext_dma.dmapb.r_ptr,
_probe->ext_dma.dmapb.avail);
else
return SOF_TASK_STATE_RESCHEDULE;
if (err < 0) {
tr_err(&pr_tr, "probe_task(): dma_copy_to_host_nowait() failed.");
tr_err(&pr_tr, "probe_task(): dma_copy_to_host() failed.");
return err;
}

View File

@ -83,10 +83,10 @@ static enum task_state trace_work(void *data)
d->copy_in_progress = 1;
/* copy this section to host */
size = dma_copy_to_host_nowait(&d->dc, config, d->posn.host_offset,
buffer->r_ptr, size);
size = dma_copy_to_host(&d->dc, config, d->posn.host_offset,
buffer->r_ptr, size);
if (size < 0) {
tr_err(&dt_tr, "trace_work(): dma_copy_to_host_nowait() failed");
tr_err(&dt_tr, "trace_work(): dma_copy_to_host() failed");
goto out;
}