mirror of https://github.com/thesofproject/sof.git
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:
parent
5afc494671
commit
443b21de4b
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue