summaryrefslogtreecommitdiff
path: root/drivers/dma/idxd/dma.c
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2021-10-27 00:36:36 +0300
committerVinod Koul <vkoul@kernel.org>2021-11-22 08:51:26 +0300
commitf6d442f7088cbf5e2ac4561aca6888380239d5b9 (patch)
tree6b982d59f3a3158126ba97ce09adacb603e0c3ba /drivers/dma/idxd/dma.c
parentbd5970a0d01f8e45af9b2e2cf1d245b84ea757ba (diff)
downloadlinux-f6d442f7088cbf5e2ac4561aca6888380239d5b9.tar.xz
dmaengine: idxd: handle invalid interrupt handle descriptors
Handle a descriptor that has been marked with invalid interrupt handle error in status. Create a work item that will resubmit the descriptor. This typically happens when the driver has handled the revoke interrupt handle event and has a new interrupt handle. Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/163528419601.3925689.4166517602890523193.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/idxd/dma.c')
-rw-r--r--drivers/dma/idxd/dma.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c
index 375dbae18583..2ce873994e33 100644
--- a/drivers/dma/idxd/dma.c
+++ b/drivers/dma/idxd/dma.c
@@ -24,18 +24,24 @@ void idxd_dma_complete_txd(struct idxd_desc *desc,
enum idxd_complete_type comp_type,
bool free_desc)
{
+ struct idxd_device *idxd = desc->wq->idxd;
struct dma_async_tx_descriptor *tx;
struct dmaengine_result res;
int complete = 1;
- if (desc->completion->status == DSA_COMP_SUCCESS)
+ if (desc->completion->status == DSA_COMP_SUCCESS) {
res.result = DMA_TRANS_NOERROR;
- else if (desc->completion->status)
+ } else if (desc->completion->status) {
+ if (idxd->request_int_handles && comp_type != IDXD_COMPLETE_ABORT &&
+ desc->completion->status == DSA_COMP_INT_HANDLE_INVAL &&
+ idxd_queue_int_handle_resubmit(desc))
+ return;
res.result = DMA_TRANS_WRITE_FAILED;
- else if (comp_type == IDXD_COMPLETE_ABORT)
+ } else if (comp_type == IDXD_COMPLETE_ABORT) {
res.result = DMA_TRANS_ABORTED;
- else
+ } else {
complete = 0;
+ }
tx = &desc->txd;
if (complete && tx->cookie) {