This is a note to let you know that I've just added the patch titled io-wq: fix queue stalling race to the 5.14-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-fix-queue-stalling-race.patch and it can be found in the queue-5.14 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From foo@baz Mon Nov 15 03:27:04 PM CET 2021 From: Jens Axboe <axboe@xxxxxxxxx> Date: Tue, 31 Aug 2021 13:53:00 -0600 Subject: io-wq: fix queue stalling race From: Jens Axboe <axboe@xxxxxxxxx> commit 0242f6426ea78fbe3933b44f8c55ae93ec37f6cc upstream. We need to set the stalled bit early, before we drop the lock for adding us to the stall hash queue. If not, then we can race with new work being queued between adding us to the stall hash and io_worker_handle_work() marking us stalled. Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/io-wq.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) --- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -436,8 +436,7 @@ static bool io_worker_can_run_work(struc } static struct io_wq_work *io_get_next_work(struct io_wqe *wqe, - struct io_worker *worker, - bool *stalled) + struct io_worker *worker) __must_hold(wqe->lock) { struct io_wq_work_node *node, *prev; @@ -475,10 +474,14 @@ static struct io_wq_work *io_get_next_wo } if (stall_hash != -1U) { + /* + * Set this before dropping the lock to avoid racing with new + * work being added and clearing the stalled bit. + */ + wqe->flags |= IO_WQE_FLAG_STALLED; raw_spin_unlock(&wqe->lock); io_wait_on_hash(wqe, stall_hash); raw_spin_lock(&wqe->lock); - *stalled = true; } return NULL; @@ -518,7 +521,6 @@ static void io_worker_handle_work(struct do { struct io_wq_work *work; - bool stalled; get_next: /* * If we got some work, mark us as busy. If we didn't, but @@ -527,12 +529,9 @@ get_next: * can't make progress, any work completion or insertion will * clear the stalled flag. */ - stalled = false; - work = io_get_next_work(wqe, worker, &stalled); + work = io_get_next_work(wqe, worker); if (work) __io_worker_busy(wqe, worker, work); - else if (stalled) - wqe->flags |= IO_WQE_FLAG_STALLED; raw_spin_unlock_irq(&wqe->lock); if (!work) Patches currently in stable-queue which might be from axboe@xxxxxxxxx are queue-5.14/floppy-fix-add_disk-assumption-on-exit-due-to-new-de.patch queue-5.14/block-ataflop-more-blk-mq-refactoring-fixes.patch queue-5.14/nbd-fix-use-after-free-in-pid_show.patch queue-5.14/floppy-use-blk_cleanup_disk.patch queue-5.14/block-ataflop-use-the-blk_cleanup_disk-helper.patch queue-5.14/md-update-superblock-after-changing-rdev-flags-in-st.patch queue-5.14/alsa-hda-reduce-udelay-at-skl-position-reporting.patch queue-5.14/block-ataflop-add-registration-bool-before-calling-d.patch queue-5.14/md-raid1-only-allocate-write-behind-bio-for-writemostly-device.patch queue-5.14/ataflop-remove-ataflop_probe_lock-mutex.patch queue-5.14/block-remove-inaccurate-requeue-check.patch queue-5.14/block-ataflop-provide-a-helper-for-cleanup-up-an-ata.patch queue-5.14/floppy-fix-calling-platform_device_unregister-on-inv.patch queue-5.14/io-wq-ensure-that-hash-wait-lock-is-irq-disabling.patch queue-5.14/block-schedule-queue-restart-after-blk_sts_zone_reso.patch queue-5.14/io-wq-fix-queue-stalling-race.patch queue-5.14/block-ataflop-fix-breakage-introduced-at-blk-mq-refa.patch queue-5.14/io-wq-serialize-hash-clear-with-wakeup.patch queue-5.14/nvdimm-btt-do-not-call-del_gendisk-if-not-needed.patch queue-5.14/blk-cgroup-synchronize-blkg-creation-against-policy-.patch queue-5.14/nbd-fix-possible-overflow-for-first_minor-in-nbd_dev.patch queue-5.14/nbd-fix-max-value-for-first_minor.patch queue-5.14/block-bump-max-plugged-deferred-size-from-16-to-32.patch