Patch "io-wq: write next_work before dropping acct_lock" has been added to the 6.6-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

    io-wq: write next_work before dropping acct_lock

to the 6.6-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:
     io-wq-write-next_work-before-dropping-acct_lock.patch
and it can be found in the queue-6.6 subdirectory.

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



commit d081bd376b39336e837aa3b30e5f7856560a392b
Author: Gabriel Krisman Bertazi <krisman@xxxxxxx>
Date:   Mon Apr 15 22:10:53 2024 -0400

    io-wq: write next_work before dropping acct_lock
    
    [ Upstream commit 068c27e32e51e94e4a9eb30ae85f4097a3602980 ]
    
    Commit 361aee450c6e ("io-wq: add intermediate work step between pending
    list and active work") closed a race between a cancellation and the work
    being removed from the wq for execution.  To ensure the request is
    always reachable by the cancellation, we need to move it within the wq
    lock, which also synchronizes the cancellation.  But commit
    42abc95f05bf ("io-wq: decouple work_list protection from the big
    wqe->lock") replaced the wq lock here and accidentally reintroduced the
    race by releasing the acct_lock too early.
    
    In other words:
    
            worker                |     cancellation
    work = io_get_next_work()     |
    raw_spin_unlock(&acct->lock); |
                                  |
                                  | io_acct_cancel_pending_work
                                  | io_wq_worker_cancel()
    worker->next_work = work
    
    Using acct_lock is still enough since we synchronize on it on
    io_acct_cancel_pending_work.
    
    Fixes: 42abc95f05bf ("io-wq: decouple work_list protection from the big wqe->lock")
    Signed-off-by: Gabriel Krisman Bertazi <krisman@xxxxxxx>
    Link: https://lore.kernel.org/r/20240416021054.3940-2-krisman@xxxxxxx
    Signed-off-by: Jens Axboe <axboe@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
index 522196dfb0ff5..318ed067dbf64 100644
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -564,10 +564,7 @@ static void io_worker_handle_work(struct io_wq_acct *acct,
 		 * clear the stalled flag.
 		 */
 		work = io_get_next_work(acct, worker);
-		raw_spin_unlock(&acct->lock);
 		if (work) {
-			__io_worker_busy(wq, worker);
-
 			/*
 			 * Make sure cancelation can find this, even before
 			 * it becomes the active work. That avoids a window
@@ -578,9 +575,15 @@ static void io_worker_handle_work(struct io_wq_acct *acct,
 			raw_spin_lock(&worker->lock);
 			worker->next_work = work;
 			raw_spin_unlock(&worker->lock);
-		} else {
-			break;
 		}
+
+		raw_spin_unlock(&acct->lock);
+
+		if (!work)
+			break;
+
+		__io_worker_busy(wq, worker);
+
 		io_assign_current_work(worker, work);
 		__set_current_state(TASK_RUNNING);
 




[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