--- /dev/null
+From foo@baz Mon Nov 15 03:27:04 PM CET 2021
+From: Jens Axboe <axboe@kernel.dk>
+Date: Tue, 31 Aug 2021 06:57:25 -0600
+Subject: io-wq: ensure that hash wait lock is IRQ disabling
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit 08bdbd39b58474d762242e1fadb7f2eb9ffcca71 upstream.
+
+A previous commit removed the IRQ safety of the worker and wqe locks,
+but that left one spot of the hash wait lock now being done without
+already having IRQs disabled.
+
+Ensure that we use the right locking variant for the hashed waitqueue
+lock.
+
+Fixes: a9a4aa9fbfc5 ("io-wq: wqe and worker locks no longer need to be IRQ safe")
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/io-wq.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/io-wq.c
++++ b/fs/io-wq.c
+@@ -405,7 +405,7 @@ static void io_wait_on_hash(struct io_wq
+ {
+ struct io_wq *wq = wqe->wq;
+
+- spin_lock(&wq->hash->wait.lock);
++ spin_lock_irq(&wq->hash->wait.lock);
+ if (list_empty(&wqe->wait.entry)) {
+ __add_wait_queue(&wq->hash->wait, &wqe->wait);
+ if (!test_bit(hash, &wq->hash->map)) {
+@@ -413,7 +413,7 @@ static void io_wait_on_hash(struct io_wq
+ list_del_init(&wqe->wait.entry);
+ }
+ }
+- spin_unlock(&wq->hash->wait.lock);
++ spin_unlock_irq(&wq->hash->wait.lock);
+ }
+
+ /*
--- /dev/null
+From foo@baz Mon Nov 15 03:27:04 PM CET 2021
+From: Jens Axboe <axboe@kernel.dk>
+Date: Tue, 31 Aug 2021 13:53:00 -0600
+Subject: io-wq: fix queue stalling race
+
+From: Jens Axboe <axboe@kernel.dk>
+
+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@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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)
--- /dev/null
+From foo@baz Mon Nov 15 03:27:04 PM CET 2021
+From: Jens Axboe <axboe@kernel.dk>
+Date: Sun, 14 Nov 2021 07:36:47 -0700
+Subject: io-wq: serialize hash clear with wakeup
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit d3e3c102d107bb84251455a298cf475f24bab995 upstream.
+
+We need to ensure that we serialize the stalled and hash bits with the
+wait_queue wait handler, or we could be racing with someone modifying
+the hashed state after we find it busy, but before we then give up and
+wait for it to be cleared. This can cause random delays or stalls when
+handling buffered writes for many files, where some of these files cause
+hash collisions between the worker threads.
+
+Cc: stable@vger.kernel.org
+Reported-by: Daniel Black <daniel@mariadb.org>
+Fixes: e941894eae31 ("io-wq: make buffered file write hashed work map per-ctx")
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/io-wq.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+--- a/fs/io-wq.c
++++ b/fs/io-wq.c
+@@ -401,9 +401,10 @@ static inline unsigned int io_get_work_h
+ return work->flags >> IO_WQ_HASH_SHIFT;
+ }
+
+-static void io_wait_on_hash(struct io_wqe *wqe, unsigned int hash)
++static bool io_wait_on_hash(struct io_wqe *wqe, unsigned int hash)
+ {
+ struct io_wq *wq = wqe->wq;
++ bool ret = false;
+
+ spin_lock_irq(&wq->hash->wait.lock);
+ if (list_empty(&wqe->wait.entry)) {
+@@ -411,9 +412,11 @@ static void io_wait_on_hash(struct io_wq
+ if (!test_bit(hash, &wq->hash->map)) {
+ __set_current_state(TASK_RUNNING);
+ list_del_init(&wqe->wait.entry);
++ ret = true;
+ }
+ }
+ spin_unlock_irq(&wq->hash->wait.lock);
++ return ret;
+ }
+
+ /*
+@@ -474,14 +477,21 @@ static struct io_wq_work *io_get_next_wo
+ }
+
+ if (stall_hash != -1U) {
++ bool unstalled;
++
+ /*
+ * 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);
++ unstalled = io_wait_on_hash(wqe, stall_hash);
+ raw_spin_lock(&wqe->lock);
++ if (unstalled) {
++ wqe->flags &= ~IO_WQE_FLAG_STALLED;
++ if (wq_has_sleeper(&wqe->wq->hash->wait))
++ wake_up(&wqe->wq->hash->wait);
++ }
+ }
+
+ return NULL;
+@@ -562,11 +572,14 @@ get_next:
+ io_wqe_enqueue(wqe, linked);
+
+ if (hash != -1U && !next_hashed) {
++ /* serialize hash clear with wake_up() */
++ spin_lock_irq(&wq->hash->wait.lock);
+ clear_bit(hash, &wq->hash->map);
++ wqe->flags &= ~IO_WQE_FLAG_STALLED;
++ spin_unlock_irq(&wq->hash->wait.lock);
+ if (wq_has_sleeper(&wq->hash->wait))
+ wake_up(&wq->hash->wait);
+ raw_spin_lock_irq(&wqe->lock);
+- wqe->flags &= ~IO_WQE_FLAG_STALLED;
+ /* skip unnecessary unlock-lock wqe->lock */
+ if (!work)
+ goto get_next;
9p-net-fix-missing-error-check-in-p9_check_errors.patch
mm-filemap.c-remove-bogus-vm_bug_on.patch
memcg-prohibit-unconditional-exceeding-the-limit-of-dying-tasks.patch
+io-wq-ensure-that-hash-wait-lock-is-irq-disabling.patch
+io-wq-fix-queue-stalling-race.patch
+io-wq-serialize-hash-clear-with-wakeup.patch