FAILED: patch "[PATCH] dmaengine: idxd: fix descriptor flushing locking" failed to apply to 5.15-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 23a50c8035655c5a1d9b52c878b3ebf7b6b83eea Mon Sep 17 00:00:00 2001
From: Dave Jiang <[email protected]>
Date: Mon, 13 Dec 2021 11:51:29 -0700
Subject: [PATCH] dmaengine: idxd: fix descriptor flushing locking
The descriptor flushing for shutdown is not holding the irq_entry list lock. If there's ongoing interrupt completion handling, this can corrupt the list. Add locking to protect list walking. Also refactor the code so it's more compact.
drivers/dma/idxd/init.c +15 -14
@@ -689,26 +689,28 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)return rc; } -static void idxd_flush_pending_llist (struct idxd_irq_entry *ie) +static void idxd_flush_pending_descs (struct idxd_irq_entry *ie) {struct idxd_desc *desc, *itr;struct llist_node *head; +LIST_HEAD (flist); +enum idxd_complete_type ctype; +spin_lock (&ie->list_lock); head =llist_del_all (&ie->pending_llist); -if (!head) -return ; - -llist_for_each_entry_safe (desc, itr, head, llnode) -idxd_dma_complete_txd (desc,IDXD_COMPLETE_ABORT , true); -} +if (head) { +llist_for_each_entry_safe (desc, itr, head, llnode) +list_add_tail (&desc->list, &ie->work_list); + } -static void idxd_flush_work_list (struct idxd_irq_entry *ie) -{ -struct idxd_desc *desc, *iter; +list_for_each_entry_safe (desc, itr, &ie->work_list, list) +list_move_tail (&desc->list, &flist); +spin_unlock (&ie->list_lock); -list_for_each_entry_safe (desc, iter, &ie->work_list, list) { +list_for_each_entry_safe (desc, itr, &flist, list) {list_del (&desc->list); -idxd_dma_complete_txd (desc,IDXD_COMPLETE_ABORT , true); + ctype = desc->completion->status ?IDXD_COMPLETE_NORMAL :IDXD_COMPLETE_ABORT ; +idxd_dma_complete_txd (desc, ctype, true); } }
@@ -762,8 +764,7 @@ static void idxd_shutdown(struct pci_dev *pdev)synchronize_irq (irq_entry->vector);if (i ==0 )continue ; -idxd_flush_pending_llist (irq_entry); -idxd_flush_work_list (irq_entry); +idxd_flush_pending_descs (irq_entry); }flush_workqueue (idxd->wq); }