Skip to content

Commit 068c27e

Browse files
krismanaxboe
authored andcommitted
io-wq: write next_work before dropping acct_lock
Commit 361aee4 ("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 42abc95 ("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: 42abc95 ("io-wq: decouple work_list protection from the big wqe->lock") Signed-off-by: Gabriel Krisman Bertazi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent c4ce0ab commit 068c27e

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

io_uring/io-wq.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,7 @@ static void io_worker_handle_work(struct io_wq_acct *acct,
564564
* clear the stalled flag.
565565
*/
566566
work = io_get_next_work(acct, worker);
567-
raw_spin_unlock(&acct->lock);
568567
if (work) {
569-
__io_worker_busy(wq, worker);
570-
571568
/*
572569
* Make sure cancelation can find this, even before
573570
* it becomes the active work. That avoids a window
@@ -578,9 +575,15 @@ static void io_worker_handle_work(struct io_wq_acct *acct,
578575
raw_spin_lock(&worker->lock);
579576
worker->next_work = work;
580577
raw_spin_unlock(&worker->lock);
581-
} else {
582-
break;
583578
}
579+
580+
raw_spin_unlock(&acct->lock);
581+
582+
if (!work)
583+
break;
584+
585+
__io_worker_busy(wq, worker);
586+
584587
io_assign_current_work(worker, work);
585588
__set_current_state(TASK_RUNNING);
586589

0 commit comments

Comments
 (0)