Commit 6247cdc2 authored by Dan Williams's avatar Dan Williams

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: default avatarSaeed Bishara <saeed.bishara@gmail.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent c5d2b9f4
...@@ -80,6 +80,7 @@ dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) ...@@ -80,6 +80,7 @@ dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
{ {
enum dma_status status; enum dma_status status;
struct dma_async_tx_descriptor *iter; struct dma_async_tx_descriptor *iter;
struct dma_async_tx_descriptor *parent;
if (!tx) if (!tx)
return DMA_SUCCESS; return DMA_SUCCESS;
...@@ -87,8 +88,15 @@ dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) ...@@ -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 */ /* poll through the dependency chain, return when tx is complete */
do { do {
iter = tx; 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); status = dma_sync_wait(iter->chan, iter->cookie);
} while (status == DMA_IN_PROGRESS || (iter != tx)); } while (status == DMA_IN_PROGRESS || (iter != tx));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment