diff options
author | Vinod Koul <vkoul@kernel.org> | 2022-01-05 08:18:05 +0100 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2022-01-05 08:18:05 +0100 |
commit | 5cb664fbeba0a11592c1d2774833a4cc49d1ca19 (patch) | |
tree | f5eb47d25d0b90cebbe46d0cbe33bf39bc339eef /drivers/dma/idxd | |
parent | dmaengine: uniphier-xdmac: Fix type of address variables (diff) | |
parent | dmaengine: st_fdma: fix MODULE_ALIAS (diff) | |
download | linux-5cb664fbeba0a11592c1d2774833a4cc49d1ca19.tar.xz linux-5cb664fbeba0a11592c1d2774833a4cc49d1ca19.zip |
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')
-rw-r--r-- | drivers/dma/idxd/irq.c | 2 | ||||
-rw-r--r-- | drivers/dma/idxd/submit.c | 18 |
2 files changed, 18 insertions, 2 deletions
diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index 0b0055a0ad2a..925171e9738c 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -318,10 +318,10 @@ halt: INIT_WORK(&idxd->work, idxd_device_reinit); queue_work(idxd->wq, &idxd->work); } else { - spin_lock(&idxd->dev_lock); idxd->state = IDXD_DEV_HALTED; idxd_wqs_quiesce(idxd); idxd_wqs_unmap_portal(idxd); + spin_lock(&idxd->dev_lock); idxd_device_clear_state(idxd); dev_err(&idxd->pdev->dev, "idxd halted, need %s.\n", 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); + } } /* |