summaryrefslogtreecommitdiff
path: root/drivers/dma/idxd/submit.c
diff options
context:
space:
mode:
authorVinod Koul <vkoul@kernel.org>2022-01-05 10:18:05 +0300
committerVinod Koul <vkoul@kernel.org>2022-01-05 10:18:05 +0300
commit5cb664fbeba0a11592c1d2774833a4cc49d1ca19 (patch)
treef5eb47d25d0b90cebbe46d0cbe33bf39bc339eef /drivers/dma/idxd/submit.c
parent105a8c525675bb7d4d64871f9b2edf39460de881 (diff)
parent822c9f2b833c53fc67e8adf6f63ecc3ea24d502c (diff)
downloadlinux-5cb664fbeba0a11592c1d2774833a4cc49d1ca19.tar.xz
Merge branch 'fixes' into next
We have a conflict in idxd driver between 'fixes' and 'next' and there are patches dependent on this so, merge the 'fixes' branch into next
Diffstat (limited to 'drivers/dma/idxd/submit.c')
-rw-r--r--drivers/dma/idxd/submit.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c
index 569815a84e95..11ac06be1f0a 100644
--- a/drivers/dma/idxd/submit.c
+++ b/drivers/dma/idxd/submit.c
@@ -97,6 +97,7 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
{
struct idxd_desc *d, *t, *found = NULL;
struct llist_node *head;
+ LIST_HEAD(flist);
desc->completion->status = IDXD_COMP_DESC_ABORT;
/*
@@ -111,7 +112,11 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
found = desc;
continue;
}
- list_add_tail(&desc->list, &ie->work_list);
+
+ if (d->completion->status)
+ list_add_tail(&d->list, &flist);
+ else
+ list_add_tail(&d->list, &ie->work_list);
}
}
@@ -121,6 +126,17 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
if (found)
idxd_dma_complete_txd(found, IDXD_COMPLETE_ABORT, false);
+
+ /*
+ * completing the descriptor will return desc to allocator and
+ * the desc can be acquired by a different process and the
+ * desc->list can be modified. Delete desc from list so the
+ * list trasversing does not get corrupted by the other process.
+ */
+ list_for_each_entry_safe(d, t, &flist, list) {
+ list_del_init(&d->list);
+ idxd_dma_complete_txd(found, IDXD_COMPLETE_ABORT, true);
+ }
}
/*