summaryrefslogtreecommitdiff
path: root/drivers/dma/idxd/submit.c
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2021-08-06 20:37:40 +0300
committerVinod Koul <vkoul@kernel.org>2021-08-25 14:30:24 +0300
commit0b030f54f094fcd42f4a607a675c1851129a58c8 (patch)
tree679418b53ef62fcf2e12685d764acc36930e06f0 /drivers/dma/idxd/submit.c
parent9760383b22edbfa407a1647969c26d62a501631f (diff)
downloadlinux-0b030f54f094fcd42f4a607a675c1851129a58c8.tar.xz
dmaengine: idxd: make submit failure path consistent on desc freeing
The submission path for dmaengine API does not do descriptor freeing on failure. Also, with the abort mechanism, the freeing of descriptor happens when the abort callback is completed. Therefore free descriptor on all error paths for submission call to make things consistent. Also remove the double free that would happen on abort in idxd_dma_tx_submit() call. Fixes: 6b4b87f2c31a ("dmaengine: idxd: fix submission race window") Signed-off-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/162827146072.3459011.10255348500504659810.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/idxd/submit.c')
-rw-r--r--drivers/dma/idxd/submit.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c
index 4b514c63af15..de76fb4abac2 100644
--- a/drivers/dma/idxd/submit.c
+++ b/drivers/dma/idxd/submit.c
@@ -139,11 +139,15 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc)
void __iomem *portal;
int rc;
- if (idxd->state != IDXD_DEV_ENABLED)
+ if (idxd->state != IDXD_DEV_ENABLED) {
+ idxd_free_desc(wq, desc);
return -EIO;
+ }
- if (!percpu_ref_tryget_live(&wq->wq_active))
+ if (!percpu_ref_tryget_live(&wq->wq_active)) {
+ idxd_free_desc(wq, desc);
return -ENXIO;
+ }
portal = idxd_wq_portal_addr(wq);
@@ -175,8 +179,11 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc)
rc = enqcmds(portal, desc->hw);
if (rc < 0) {
percpu_ref_put(&wq->wq_active);
+ /* abort operation frees the descriptor */
if (ie)
llist_abort_desc(wq, ie, desc);
+ else
+ idxd_free_desc(wq, desc);
return rc;
}
}