Patch "dmaengine: idxd: fix missed completion on abort path" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    dmaengine: idxd: fix missed completion on abort path

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     dmaengine-idxd-fix-missed-completion-on-abort-path.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit e1d11e16425fd96b8327ccdac2e206ec4af3f79d
Author: Dave Jiang <dave.jiang@xxxxxxxxx>
Date:   Wed Dec 8 10:01:27 2021 -0700

    dmaengine: idxd: fix missed completion on abort path
    
    [ Upstream commit 8affd8a4b5ce356c8900cfb037674f3a4a11fbdb ]
    
    Ming reported that with the abort path of the descriptor submission, there
    can be a window where a completed descriptor can be missed to be completed
    by the irq completion thread:
    
    CPU A                           CPU B
    Submit (successful)
    
    Submit (fail)
                                    irq_process_work_list() // empty
    
    llist_abort_desc()
    // remove all descs from pending list
    
                                    irq_process_pending_llist() // empty
                                    exit idxd_wq_thread() with no processing
    
    Add opportunistic descriptor completion in the abort path in order to
    remove the missed completion.
    
    Fixes: 6b4b87f2c31a ("dmaengine: idxd: fix submission race window")
    Reported-by: Ming Li <ming4.li@xxxxxxxxx>
    Signed-off-by: Dave Jiang <dave.jiang@xxxxxxxxx>
    Link: https://lore.kernel.org/r/163898288714.443911.16084982766671976640.stgit@xxxxxxxxxxxxxxxxxxxxxxxxxx
    Signed-off-by: Vinod Koul <vkoul@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c
index de76fb4abac24..83452fbbb168b 100644
--- a/drivers/dma/idxd/submit.c
+++ b/drivers/dma/idxd/submit.c
@@ -106,6 +106,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;
 	/*
@@ -120,7 +121,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);
 		}
 	}
 
@@ -130,6 +135,17 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie,
 
 	if (found)
 		complete_desc(found, IDXD_COMPLETE_ABORT);
+
+	/*
+	 * complete_desc() 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);
+		complete_desc(d, IDXD_COMPLETE_NORMAL);
+	}
 }
 
 int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc)



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux