mirror of https://gitee.com/openkylin/linux.git
async_tx: fix dma_wait_for_async_tx
Fix dma_wait_for_async_tx to not loop forever in the case where a dependency chain is longer than two entries. This condition will not happen with current in-kernel drivers, but fix it for future drivers. Found-by: Saeed Bishara <saeed.bishara@gmail.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
c5d2b9f444
commit
6247cdc2cd
|
@ -80,6 +80,7 @@ dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
|
|||
{
|
||||
enum dma_status status;
|
||||
struct dma_async_tx_descriptor *iter;
|
||||
struct dma_async_tx_descriptor *parent;
|
||||
|
||||
if (!tx)
|
||||
return DMA_SUCCESS;
|
||||
|
@ -87,8 +88,15 @@ dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
|
|||
/* poll through the dependency chain, return when tx is complete */
|
||||
do {
|
||||
iter = tx;
|
||||
while (iter->cookie == -EBUSY)
|
||||
iter = iter->parent;
|
||||
|
||||
/* find the root of the unsubmitted dependency chain */
|
||||
while (iter->cookie == -EBUSY) {
|
||||
parent = iter->parent;
|
||||
if (parent && parent->cookie == -EBUSY)
|
||||
iter = iter->parent;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
status = dma_sync_wait(iter->chan, iter->cookie);
|
||||
} while (status == DMA_IN_PROGRESS || (iter != tx));
|
||||
|
|
Loading…
Reference in New Issue