diff options
author | Vinod Koul <vkoul@kernel.org> | 2022-01-05 10:18:05 +0300 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2022-01-05 10:18:05 +0300 |
commit | 5cb664fbeba0a11592c1d2774833a4cc49d1ca19 (patch) | |
tree | f5eb47d25d0b90cebbe46d0cbe33bf39bc339eef /drivers/dma/idxd/submit.c | |
parent | 105a8c525675bb7d4d64871f9b2edf39460de881 (diff) | |
parent | 822c9f2b833c53fc67e8adf6f63ecc3ea24d502c (diff) | |
download | linux-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.c | 18 |
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); + } } /* |