30 Oct
2015
30 Oct
'15
3:16 p.m.
On 10/29/2015 10:59 PM, Andy Shevchenko wrote:
On Tue, Oct 20, 2015 at 12:46 PM, Lars-Peter Clausen lars@metafoo.de wrote:
The DMAengine API has a long standing race condition that is inherent to the API itself. Calling dmaengine_terminate_all() is supposed to stop and abort any pending or active transfers that have previously been submitted. Unfortunately it is possible that this operation races against a currently running (or with some drivers also scheduled) completion callback.
[]
+/**
- dmaengine_terminate_sync() - Terminate all active DMA transfers
- @chan: The channel for which to terminate the transfers
- Calling this function will terminate all active and pending transfers
- that have previously been submitted to the channel. It is similar to
- dmaengine_terminate_async() but guarantees that the DMA transfer has actually
- stopped and that all complete callbacks have finished running when the
- function returns.
- This function must only be called from non-atomic context and must not be
- called from within a complete callback of a descriptor submitted on the same
- channel.
- */
+static inline int dmaengine_terminate_sync(struct dma_chan *chan) +{
int ret;
Might be a good idea to add might_sleep(); here.
Sound like a good idea, thanks, I'll add it (in dmaengine_synchronize() though).
ret = dmaengine_terminate_async(chan);
if (ret)
return ret;
dmaengine_synchronize(chan);
return 0;
+}