]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop sbitmap patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Oct 2022 18:51:10 +0000 (20:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Oct 2022 18:51:10 +0000 (20:51 +0200)
20 files changed:
queue-4.19/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch [deleted file]
queue-4.19/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch [deleted file]
queue-4.19/series
queue-5.10/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch [deleted file]
queue-5.10/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch [deleted file]
queue-5.10/series
queue-5.15/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch [deleted file]
queue-5.15/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch [deleted file]
queue-5.15/series
queue-5.19/revert-sbitmap-fix-batched-wait_cnt-accounting.patch [deleted file]
queue-5.19/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch [deleted file]
queue-5.19/sbitmap-fix-batched-wait_cnt-accounting.patch [deleted file]
queue-5.19/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch [deleted file]
queue-5.19/series
queue-5.4/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch [deleted file]
queue-5.4/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch [deleted file]
queue-5.4/series
queue-6.0/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch [deleted file]
queue-6.0/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch [deleted file]
queue-6.0/series

diff --git a/queue-4.19/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch b/queue-4.19/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
deleted file mode 100644 (file)
index 9201026..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From e0483e76e17af926690bb0151e2e7a83ad2e9a88 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 8 Sep 2022 15:09:37 +0200
-Subject: sbitmap: Avoid leaving waitqueue in invalid state in __sbq_wake_up()
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit 48c033314f372478548203c583529f53080fd078 ]
-
-When __sbq_wake_up() decrements wait_cnt to 0 but races with someone
-else waking the waiter on the waitqueue (so the waitqueue becomes
-empty), it exits without reseting wait_cnt to wake_batch number. Once
-wait_cnt is 0, nobody will ever reset the wait_cnt or wake the new
-waiters resulting in possible deadlocks or busyloops. Fix the problem by
-making sure we reset wait_cnt even if we didn't wake up anybody in the
-end.
-
-Fixes: 040b83fcecfb ("sbitmap: fix possible io hung due to lost wakeup")
-Reported-by: Keith Busch <kbusch@kernel.org>
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220908130937.2795-1-jack@suse.cz
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index 474e014a2b6e..6913f2c4f2c8 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -463,6 +463,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       struct sbq_wait_state *ws;
-       unsigned int wake_batch;
-       int wait_cnt;
-+      bool ret;
-       ws = sbq_wake_ptr(sbq);
-       if (!ws)
-@@ -473,12 +474,23 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-        * For concurrent callers of this, callers should call this function
-        * again to wakeup a new batch on a different 'ws'.
-        */
--      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+      if (wait_cnt < 0)
-               return true;
-+      /*
-+       * If we decremented queue without waiters, retry to avoid lost
-+       * wakeups.
-+       */
-       if (wait_cnt > 0)
--              return false;
-+              return !waitqueue_active(&ws->wait);
-+      /*
-+       * When wait_cnt == 0, we have to be particularly careful as we are
-+       * responsible to reset wait_cnt regardless whether we've actually
-+       * woken up anybody. But in case we didn't wakeup anybody, we still
-+       * need to retry.
-+       */
-+      ret = !waitqueue_active(&ws->wait);
-       wake_batch = READ_ONCE(sbq->wake_batch);
-       /*
-@@ -507,7 +519,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       sbq_index_atomic_inc(&sbq->wake_index);
-       atomic_set(&ws->wait_cnt, wake_batch);
--      return false;
-+      return ret;
- }
- void sbitmap_queue_wake_up(struct sbitmap_queue *sbq)
--- 
-2.35.1
-
diff --git a/queue-4.19/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch b/queue-4.19/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
deleted file mode 100644 (file)
index 71cdb50..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-From ff0fe7d067ce297123456fb491d402905450ddd0 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 3 Aug 2022 20:15:04 +0800
-Subject: sbitmap: fix possible io hung due to lost wakeup
-
-From: Yu Kuai <yukuai3@huawei.com>
-
-[ Upstream commit 040b83fcecfb86f3225d3a5de7fd9b3fbccf83b4 ]
-
-There are two problems can lead to lost wakeup:
-
-1) invalid wakeup on the wrong waitqueue:
-
-For example, 2 * wake_batch tags are put, while only wake_batch threads
-are woken:
-
-__sbq_wake_up
- atomic_cmpxchg -> reset wait_cnt
-                       __sbq_wake_up -> decrease wait_cnt
-                       ...
-                       __sbq_wake_up -> wait_cnt is decreased to 0 again
-                        atomic_cmpxchg
-                        sbq_index_atomic_inc -> increase wake_index
-                        wake_up_nr -> wake up and waitqueue might be empty
- sbq_index_atomic_inc -> increase again, one waitqueue is skipped
- wake_up_nr -> invalid wake up because old wakequeue might be empty
-
-To fix the problem, increasing 'wake_index' before resetting 'wait_cnt'.
-
-2) 'wait_cnt' can be decreased while waitqueue is empty
-
-As pointed out by Jan Kara, following race is possible:
-
-CPU1                           CPU2
-__sbq_wake_up                   __sbq_wake_up
- sbq_wake_ptr()                         sbq_wake_ptr() -> the same
- wait_cnt = atomic_dec_return()
- /* decreased to 0 */
- sbq_index_atomic_inc()
- /* move to next waitqueue */
- atomic_set()
- /* reset wait_cnt */
- wake_up_nr()
- /* wake up on the old waitqueue */
-                                wait_cnt = atomic_dec_return()
-                                /*
-                                 * decrease wait_cnt in the old
-                                 * waitqueue, while it can be
-                                 * empty.
-                                 */
-
-Fix the problem by waking up before updating 'wake_index' and
-'wait_cnt'.
-
-With this patch, noted that 'wait_cnt' is still decreased in the old
-empty waitqueue, however, the wakeup is redirected to a active waitqueue,
-and the extra decrement on the old empty waitqueue is not handled.
-
-Fixes: 88459642cba4 ("blk-mq: abstract tag allocation out into sbitmap library")
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Reviewed-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220803121504.212071-1-yukuai1@huaweicloud.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 55 ++++++++++++++++++++++++++++++---------------------
- 1 file changed, 33 insertions(+), 22 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index 0572ac340325..474e014a2b6e 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -469,32 +469,43 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-               return false;
-       wait_cnt = atomic_dec_return(&ws->wait_cnt);
--      if (wait_cnt <= 0) {
--              int ret;
-+      /*
-+       * For concurrent callers of this, callers should call this function
-+       * again to wakeup a new batch on a different 'ws'.
-+       */
-+      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+              return true;
--              wake_batch = READ_ONCE(sbq->wake_batch);
-+      if (wait_cnt > 0)
-+              return false;
--              /*
--               * Pairs with the memory barrier in sbitmap_queue_resize() to
--               * ensure that we see the batch size update before the wait
--               * count is reset.
--               */
--              smp_mb__before_atomic();
-+      wake_batch = READ_ONCE(sbq->wake_batch);
--              /*
--               * For concurrent callers of this, the one that failed the
--               * atomic_cmpxhcg() race should call this function again
--               * to wakeup a new batch on a different 'ws'.
--               */
--              ret = atomic_cmpxchg(&ws->wait_cnt, wait_cnt, wake_batch);
--              if (ret == wait_cnt) {
--                      sbq_index_atomic_inc(&sbq->wake_index);
--                      wake_up_nr(&ws->wait, wake_batch);
--                      return false;
--              }
-+      /*
-+       * Wake up first in case that concurrent callers decrease wait_cnt
-+       * while waitqueue is empty.
-+       */
-+      wake_up_nr(&ws->wait, wake_batch);
--              return true;
--      }
-+      /*
-+       * Pairs with the memory barrier in sbitmap_queue_resize() to
-+       * ensure that we see the batch size update before the wait
-+       * count is reset.
-+       *
-+       * Also pairs with the implicit barrier between decrementing wait_cnt
-+       * and checking for waitqueue_active() to make sure waitqueue_active()
-+       * sees result of the wakeup if atomic_dec_return() has seen the result
-+       * of atomic_set().
-+       */
-+      smp_mb__before_atomic();
-+
-+      /*
-+       * Increase wake_index before updating wait_cnt, otherwise concurrent
-+       * callers can see valid wait_cnt in old waitqueue, which can cause
-+       * invalid wakeup on the old waitqueue.
-+       */
-+      sbq_index_atomic_inc(&sbq->wake_index);
-+      atomic_set(&ws->wait_cnt, wake_batch);
-       return false;
- }
--- 
-2.35.1
-
index 7092370e2c03b964cd613b1b1e441ee851b7e283..2eaaffb2b5403790be0900c84465376c2878a818 100644 (file)
@@ -125,7 +125,6 @@ clk-berlin-add-of_node_put-for-of_get_parent.patch
 clk-tegra-fix-refcount-leak-in-tegra210_clock_init.patch
 clk-tegra-fix-refcount-leak-in-tegra114_clock_init.patch
 clk-tegra20-fix-refcount-leak-in-tegra20_clock_init.patch
-sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
 hsi-omap_ssi-fix-refcount-leak-in-ssi_probe.patch
 hsi-omap_ssi_port-fix-dma_map_sg-error-check.patch
 media-exynos4-is-fimc-is-add-of_node_put-when-breaki.patch
@@ -135,7 +134,6 @@ rdma-rxe-fix-kernel-null-pointer-dereference-error.patch
 rdma-rxe-fix-the-error-caused-by-qp-sk.patch
 dyndbg-fix-module.dyndbg-handling.patch
 dyndbg-let-query-modname-override-actual-module-name.patch
-sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
 mtd-devices-docg3-check-the-return-value-of-devm_ior.patch
 ata-fix-ata_id_sense_reporting_enabled-and-ata_id_ha.patch
 ata-fix-ata_id_has_devslp.patch
diff --git a/queue-5.10/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch b/queue-5.10/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
deleted file mode 100644 (file)
index bf09531..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From e3b91089200a0c4c3fdfe150a167b9916b4b5220 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 8 Sep 2022 15:09:37 +0200
-Subject: sbitmap: Avoid leaving waitqueue in invalid state in __sbq_wake_up()
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit 48c033314f372478548203c583529f53080fd078 ]
-
-When __sbq_wake_up() decrements wait_cnt to 0 but races with someone
-else waking the waiter on the waitqueue (so the waitqueue becomes
-empty), it exits without reseting wait_cnt to wake_batch number. Once
-wait_cnt is 0, nobody will ever reset the wait_cnt or wake the new
-waiters resulting in possible deadlocks or busyloops. Fix the problem by
-making sure we reset wait_cnt even if we didn't wake up anybody in the
-end.
-
-Fixes: 040b83fcecfb ("sbitmap: fix possible io hung due to lost wakeup")
-Reported-by: Keith Busch <kbusch@kernel.org>
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220908130937.2795-1-jack@suse.cz
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index f5213ac07da3..0658ea4bd930 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -516,6 +516,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       struct sbq_wait_state *ws;
-       unsigned int wake_batch;
-       int wait_cnt;
-+      bool ret;
-       ws = sbq_wake_ptr(sbq);
-       if (!ws)
-@@ -526,12 +527,23 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-        * For concurrent callers of this, callers should call this function
-        * again to wakeup a new batch on a different 'ws'.
-        */
--      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+      if (wait_cnt < 0)
-               return true;
-+      /*
-+       * If we decremented queue without waiters, retry to avoid lost
-+       * wakeups.
-+       */
-       if (wait_cnt > 0)
--              return false;
-+              return !waitqueue_active(&ws->wait);
-+      /*
-+       * When wait_cnt == 0, we have to be particularly careful as we are
-+       * responsible to reset wait_cnt regardless whether we've actually
-+       * woken up anybody. But in case we didn't wakeup anybody, we still
-+       * need to retry.
-+       */
-+      ret = !waitqueue_active(&ws->wait);
-       wake_batch = READ_ONCE(sbq->wake_batch);
-       /*
-@@ -560,7 +572,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       sbq_index_atomic_inc(&sbq->wake_index);
-       atomic_set(&ws->wait_cnt, wake_batch);
--      return false;
-+      return ret;
- }
- void sbitmap_queue_wake_up(struct sbitmap_queue *sbq)
--- 
-2.35.1
-
diff --git a/queue-5.10/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch b/queue-5.10/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
deleted file mode 100644 (file)
index 11e312f..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-From 6f431a716bcc47b7389973a5928e558016ddcb21 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 3 Aug 2022 20:15:04 +0800
-Subject: sbitmap: fix possible io hung due to lost wakeup
-
-From: Yu Kuai <yukuai3@huawei.com>
-
-[ Upstream commit 040b83fcecfb86f3225d3a5de7fd9b3fbccf83b4 ]
-
-There are two problems can lead to lost wakeup:
-
-1) invalid wakeup on the wrong waitqueue:
-
-For example, 2 * wake_batch tags are put, while only wake_batch threads
-are woken:
-
-__sbq_wake_up
- atomic_cmpxchg -> reset wait_cnt
-                       __sbq_wake_up -> decrease wait_cnt
-                       ...
-                       __sbq_wake_up -> wait_cnt is decreased to 0 again
-                        atomic_cmpxchg
-                        sbq_index_atomic_inc -> increase wake_index
-                        wake_up_nr -> wake up and waitqueue might be empty
- sbq_index_atomic_inc -> increase again, one waitqueue is skipped
- wake_up_nr -> invalid wake up because old wakequeue might be empty
-
-To fix the problem, increasing 'wake_index' before resetting 'wait_cnt'.
-
-2) 'wait_cnt' can be decreased while waitqueue is empty
-
-As pointed out by Jan Kara, following race is possible:
-
-CPU1                           CPU2
-__sbq_wake_up                   __sbq_wake_up
- sbq_wake_ptr()                         sbq_wake_ptr() -> the same
- wait_cnt = atomic_dec_return()
- /* decreased to 0 */
- sbq_index_atomic_inc()
- /* move to next waitqueue */
- atomic_set()
- /* reset wait_cnt */
- wake_up_nr()
- /* wake up on the old waitqueue */
-                                wait_cnt = atomic_dec_return()
-                                /*
-                                 * decrease wait_cnt in the old
-                                 * waitqueue, while it can be
-                                 * empty.
-                                 */
-
-Fix the problem by waking up before updating 'wake_index' and
-'wait_cnt'.
-
-With this patch, noted that 'wait_cnt' is still decreased in the old
-empty waitqueue, however, the wakeup is redirected to a active waitqueue,
-and the extra decrement on the old empty waitqueue is not handled.
-
-Fixes: 88459642cba4 ("blk-mq: abstract tag allocation out into sbitmap library")
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Reviewed-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220803121504.212071-1-yukuai1@huaweicloud.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 55 ++++++++++++++++++++++++++++++---------------------
- 1 file changed, 33 insertions(+), 22 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index 267aa7709416..f5213ac07da3 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -522,32 +522,43 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-               return false;
-       wait_cnt = atomic_dec_return(&ws->wait_cnt);
--      if (wait_cnt <= 0) {
--              int ret;
-+      /*
-+       * For concurrent callers of this, callers should call this function
-+       * again to wakeup a new batch on a different 'ws'.
-+       */
-+      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+              return true;
--              wake_batch = READ_ONCE(sbq->wake_batch);
-+      if (wait_cnt > 0)
-+              return false;
--              /*
--               * Pairs with the memory barrier in sbitmap_queue_resize() to
--               * ensure that we see the batch size update before the wait
--               * count is reset.
--               */
--              smp_mb__before_atomic();
-+      wake_batch = READ_ONCE(sbq->wake_batch);
--              /*
--               * For concurrent callers of this, the one that failed the
--               * atomic_cmpxhcg() race should call this function again
--               * to wakeup a new batch on a different 'ws'.
--               */
--              ret = atomic_cmpxchg(&ws->wait_cnt, wait_cnt, wake_batch);
--              if (ret == wait_cnt) {
--                      sbq_index_atomic_inc(&sbq->wake_index);
--                      wake_up_nr(&ws->wait, wake_batch);
--                      return false;
--              }
-+      /*
-+       * Wake up first in case that concurrent callers decrease wait_cnt
-+       * while waitqueue is empty.
-+       */
-+      wake_up_nr(&ws->wait, wake_batch);
--              return true;
--      }
-+      /*
-+       * Pairs with the memory barrier in sbitmap_queue_resize() to
-+       * ensure that we see the batch size update before the wait
-+       * count is reset.
-+       *
-+       * Also pairs with the implicit barrier between decrementing wait_cnt
-+       * and checking for waitqueue_active() to make sure waitqueue_active()
-+       * sees result of the wakeup if atomic_dec_return() has seen the result
-+       * of atomic_set().
-+       */
-+      smp_mb__before_atomic();
-+
-+      /*
-+       * Increase wake_index before updating wait_cnt, otherwise concurrent
-+       * callers can see valid wait_cnt in old waitqueue, which can cause
-+       * invalid wakeup on the old waitqueue.
-+       */
-+      sbq_index_atomic_inc(&sbq->wake_index);
-+      atomic_set(&ws->wait_cnt, wake_batch);
-       return false;
- }
--- 
-2.35.1
-
index 55a22ecbfb229c2d6b9c113014a677d02b4efdb5..2fa340b3df61becfcd453906954d1a6dd321db4c 100644 (file)
@@ -208,7 +208,6 @@ clk-sprd-hold-reference-returned-by-of_get_parent.patch
 clk-tegra-fix-refcount-leak-in-tegra210_clock_init.patch
 clk-tegra-fix-refcount-leak-in-tegra114_clock_init.patch
 clk-tegra20-fix-refcount-leak-in-tegra20_clock_init.patch
-sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
 hid-uclogic-make-template-placeholder-ids-generic.patch
 hid-uclogic-fix-warning-in-uclogic_rdesc_template_ap.patch
 hsi-omap_ssi-fix-refcount-leak-in-ssi_probe.patch
@@ -232,7 +231,6 @@ dyndbg-fix-static_branch-manipulation.patch
 dyndbg-fix-module.dyndbg-handling.patch
 dyndbg-let-query-modname-override-actual-module-name.patch
 dyndbg-drop-exported-dynamic_debug_exec_queries.patch
-sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
 mtd-devices-docg3-check-the-return-value-of-devm_ior.patch
 mtd-rawnand-fsl_elbc-fix-none-ecc-mode.patch
 rdma-siw-always-consume-all-skbuf-data-in-sk_data_re.patch
diff --git a/queue-5.15/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch b/queue-5.15/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
deleted file mode 100644 (file)
index 24a5caa..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From 660fdc0abb22d8d104a9ced7e4455f40c2eb27d7 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 8 Sep 2022 15:09:37 +0200
-Subject: sbitmap: Avoid leaving waitqueue in invalid state in __sbq_wake_up()
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit 48c033314f372478548203c583529f53080fd078 ]
-
-When __sbq_wake_up() decrements wait_cnt to 0 but races with someone
-else waking the waiter on the waitqueue (so the waitqueue becomes
-empty), it exits without reseting wait_cnt to wake_batch number. Once
-wait_cnt is 0, nobody will ever reset the wait_cnt or wake the new
-waiters resulting in possible deadlocks or busyloops. Fix the problem by
-making sure we reset wait_cnt even if we didn't wake up anybody in the
-end.
-
-Fixes: 040b83fcecfb ("sbitmap: fix possible io hung due to lost wakeup")
-Reported-by: Keith Busch <kbusch@kernel.org>
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220908130937.2795-1-jack@suse.cz
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index fa30f1645366..fc545994d2eb 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -534,6 +534,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       struct sbq_wait_state *ws;
-       unsigned int wake_batch;
-       int wait_cnt;
-+      bool ret;
-       ws = sbq_wake_ptr(sbq);
-       if (!ws)
-@@ -544,12 +545,23 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-        * For concurrent callers of this, callers should call this function
-        * again to wakeup a new batch on a different 'ws'.
-        */
--      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+      if (wait_cnt < 0)
-               return true;
-+      /*
-+       * If we decremented queue without waiters, retry to avoid lost
-+       * wakeups.
-+       */
-       if (wait_cnt > 0)
--              return false;
-+              return !waitqueue_active(&ws->wait);
-+      /*
-+       * When wait_cnt == 0, we have to be particularly careful as we are
-+       * responsible to reset wait_cnt regardless whether we've actually
-+       * woken up anybody. But in case we didn't wakeup anybody, we still
-+       * need to retry.
-+       */
-+      ret = !waitqueue_active(&ws->wait);
-       wake_batch = READ_ONCE(sbq->wake_batch);
-       /*
-@@ -578,7 +590,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       sbq_index_atomic_inc(&sbq->wake_index);
-       atomic_set(&ws->wait_cnt, wake_batch);
--      return false;
-+      return ret;
- }
- void sbitmap_queue_wake_up(struct sbitmap_queue *sbq)
--- 
-2.35.1
-
diff --git a/queue-5.15/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch b/queue-5.15/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
deleted file mode 100644 (file)
index 0fb53ba..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-From 9169eebf547869e1e560ce8ad702206ae9bdbee2 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 3 Aug 2022 20:15:04 +0800
-Subject: sbitmap: fix possible io hung due to lost wakeup
-
-From: Yu Kuai <yukuai3@huawei.com>
-
-[ Upstream commit 040b83fcecfb86f3225d3a5de7fd9b3fbccf83b4 ]
-
-There are two problems can lead to lost wakeup:
-
-1) invalid wakeup on the wrong waitqueue:
-
-For example, 2 * wake_batch tags are put, while only wake_batch threads
-are woken:
-
-__sbq_wake_up
- atomic_cmpxchg -> reset wait_cnt
-                       __sbq_wake_up -> decrease wait_cnt
-                       ...
-                       __sbq_wake_up -> wait_cnt is decreased to 0 again
-                        atomic_cmpxchg
-                        sbq_index_atomic_inc -> increase wake_index
-                        wake_up_nr -> wake up and waitqueue might be empty
- sbq_index_atomic_inc -> increase again, one waitqueue is skipped
- wake_up_nr -> invalid wake up because old wakequeue might be empty
-
-To fix the problem, increasing 'wake_index' before resetting 'wait_cnt'.
-
-2) 'wait_cnt' can be decreased while waitqueue is empty
-
-As pointed out by Jan Kara, following race is possible:
-
-CPU1                           CPU2
-__sbq_wake_up                   __sbq_wake_up
- sbq_wake_ptr()                         sbq_wake_ptr() -> the same
- wait_cnt = atomic_dec_return()
- /* decreased to 0 */
- sbq_index_atomic_inc()
- /* move to next waitqueue */
- atomic_set()
- /* reset wait_cnt */
- wake_up_nr()
- /* wake up on the old waitqueue */
-                                wait_cnt = atomic_dec_return()
-                                /*
-                                 * decrease wait_cnt in the old
-                                 * waitqueue, while it can be
-                                 * empty.
-                                 */
-
-Fix the problem by waking up before updating 'wake_index' and
-'wait_cnt'.
-
-With this patch, noted that 'wait_cnt' is still decreased in the old
-empty waitqueue, however, the wakeup is redirected to a active waitqueue,
-and the extra decrement on the old empty waitqueue is not handled.
-
-Fixes: 88459642cba4 ("blk-mq: abstract tag allocation out into sbitmap library")
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Reviewed-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220803121504.212071-1-yukuai1@huaweicloud.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 55 ++++++++++++++++++++++++++++++---------------------
- 1 file changed, 33 insertions(+), 22 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index b25db9be938a..fa30f1645366 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -540,32 +540,43 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-               return false;
-       wait_cnt = atomic_dec_return(&ws->wait_cnt);
--      if (wait_cnt <= 0) {
--              int ret;
-+      /*
-+       * For concurrent callers of this, callers should call this function
-+       * again to wakeup a new batch on a different 'ws'.
-+       */
-+      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+              return true;
--              wake_batch = READ_ONCE(sbq->wake_batch);
-+      if (wait_cnt > 0)
-+              return false;
--              /*
--               * Pairs with the memory barrier in sbitmap_queue_resize() to
--               * ensure that we see the batch size update before the wait
--               * count is reset.
--               */
--              smp_mb__before_atomic();
-+      wake_batch = READ_ONCE(sbq->wake_batch);
--              /*
--               * For concurrent callers of this, the one that failed the
--               * atomic_cmpxhcg() race should call this function again
--               * to wakeup a new batch on a different 'ws'.
--               */
--              ret = atomic_cmpxchg(&ws->wait_cnt, wait_cnt, wake_batch);
--              if (ret == wait_cnt) {
--                      sbq_index_atomic_inc(&sbq->wake_index);
--                      wake_up_nr(&ws->wait, wake_batch);
--                      return false;
--              }
-+      /*
-+       * Wake up first in case that concurrent callers decrease wait_cnt
-+       * while waitqueue is empty.
-+       */
-+      wake_up_nr(&ws->wait, wake_batch);
--              return true;
--      }
-+      /*
-+       * Pairs with the memory barrier in sbitmap_queue_resize() to
-+       * ensure that we see the batch size update before the wait
-+       * count is reset.
-+       *
-+       * Also pairs with the implicit barrier between decrementing wait_cnt
-+       * and checking for waitqueue_active() to make sure waitqueue_active()
-+       * sees result of the wakeup if atomic_dec_return() has seen the result
-+       * of atomic_set().
-+       */
-+      smp_mb__before_atomic();
-+
-+      /*
-+       * Increase wake_index before updating wait_cnt, otherwise concurrent
-+       * callers can see valid wait_cnt in old waitqueue, which can cause
-+       * invalid wakeup on the old waitqueue.
-+       */
-+      sbq_index_atomic_inc(&sbq->wake_index);
-+      atomic_set(&ws->wait_cnt, wake_batch);
-       return false;
- }
--- 
-2.35.1
-
index e437fc2c88a13f27cecd8c1d625d413e86227889..cdb0b8174c6e124ec78b83117a3662a979954d12 100644 (file)
@@ -291,7 +291,6 @@ clk-sprd-hold-reference-returned-by-of_get_parent.patch
 clk-tegra-fix-refcount-leak-in-tegra210_clock_init.patch
 clk-tegra-fix-refcount-leak-in-tegra114_clock_init.patch
 clk-tegra20-fix-refcount-leak-in-tegra20_clock_init.patch
-sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
 hid-uclogic-make-template-placeholder-ids-generic.patch
 hid-uclogic-fix-warning-in-uclogic_rdesc_template_ap.patch
 hsi-omap_ssi-fix-refcount-leak-in-ssi_probe.patch
@@ -317,7 +316,6 @@ dyndbg-fix-static_branch-manipulation.patch
 dyndbg-fix-module.dyndbg-handling.patch
 dyndbg-let-query-modname-override-actual-module-name.patch
 dyndbg-drop-exported-dynamic_debug_exec_queries.patch
-sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
 clk-qcom-sm6115-select-qcom_gdsc.patch
 scsi-nvme-fc-add-new-routine-nvme_fc_io_getuuid.patch
 mtd-devices-docg3-check-the-return-value-of-devm_ior.patch
diff --git a/queue-5.19/revert-sbitmap-fix-batched-wait_cnt-accounting.patch b/queue-5.19/revert-sbitmap-fix-batched-wait_cnt-accounting.patch
deleted file mode 100644 (file)
index b091770..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-From 0457860446369e63cb410d6590d32f1a99647e6e Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 4 Sep 2022 06:39:25 -0600
-Subject: Revert "sbitmap: fix batched wait_cnt accounting"
-
-From: Jens Axboe <axboe@kernel.dk>
-
-[ Upstream commit bce1b56c73826fec8caf6187f0c922ede397a5a8 ]
-
-This reverts commit 16ede66973c84f890c03584f79158dd5b2d725f5.
-
-This is causing issues with CPU stalls on my test box, revert it for
-now until we understand what is going on. It looks like infinite
-looping off sbitmap_queue_wake_up(), but hard to tell with a lot of
-CPUs hitting this issue and the console scrolling infinitely.
-
-Link: https://lore.kernel.org/linux-block/e742813b-ce5c-0d58-205b-1626f639b1bd@kernel.dk/
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Stable-dep-of: 48c033314f37 ("sbitmap: Avoid leaving waitqueue in invalid state in __sbq_wake_up()")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- block/blk-mq-tag.c      |  2 +-
- include/linux/sbitmap.h |  3 +--
- lib/sbitmap.c           | 31 ++++++++++++++-----------------
- 3 files changed, 16 insertions(+), 20 deletions(-)
-
-diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
-index 7aea93047caf..2dcd738c6952 100644
---- a/block/blk-mq-tag.c
-+++ b/block/blk-mq-tag.c
-@@ -200,7 +200,7 @@ unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data)
-                * other allocations on previous queue won't be starved.
-                */
-               if (bt != bt_prev)
--                      sbitmap_queue_wake_up(bt_prev, 1);
-+                      sbitmap_queue_wake_up(bt_prev);
-               ws = bt_wait_ptr(bt, data->hctx);
-       } while (1);
-diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
-index 4d2d5205ab58..8f5a86e210b9 100644
---- a/include/linux/sbitmap.h
-+++ b/include/linux/sbitmap.h
-@@ -575,9 +575,8 @@ void sbitmap_queue_wake_all(struct sbitmap_queue *sbq);
-  * sbitmap_queue_wake_up() - Wake up some of waiters in one waitqueue
-  * on a &struct sbitmap_queue.
-  * @sbq: Bitmap queue to wake up.
-- * @nr: Number of bits cleared.
-  */
--void sbitmap_queue_wake_up(struct sbitmap_queue *sbq, int nr);
-+void sbitmap_queue_wake_up(struct sbitmap_queue *sbq);
- /**
-  * sbitmap_queue_show() - Dump &struct sbitmap_queue information to a &struct
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index a8aae1fc5206..1f31147872e6 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -600,38 +600,34 @@ static struct sbq_wait_state *sbq_wake_ptr(struct sbitmap_queue *sbq)
-       return NULL;
- }
--static bool __sbq_wake_up(struct sbitmap_queue *sbq, int nr)
-+static bool __sbq_wake_up(struct sbitmap_queue *sbq)
- {
-       struct sbq_wait_state *ws;
--      int wake_batch, wait_cnt, cur;
-+      unsigned int wake_batch;
-+      int wait_cnt;
-       ws = sbq_wake_ptr(sbq);
--      if (!ws || !nr)
-+      if (!ws)
-               return false;
--      wake_batch = READ_ONCE(sbq->wake_batch);
--      cur = atomic_read(&ws->wait_cnt);
--      do {
--              if (cur <= 0)
--                      return true;
--              wait_cnt = cur - nr;
--      } while (!atomic_try_cmpxchg(&ws->wait_cnt, &cur, wait_cnt));
--
-+      wait_cnt = atomic_dec_return(&ws->wait_cnt);
-       /*
-        * For concurrent callers of this, callers should call this function
-        * again to wakeup a new batch on a different 'ws'.
-        */
--      if (!waitqueue_active(&ws->wait))
-+      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-               return true;
-       if (wait_cnt > 0)
-               return false;
-+      wake_batch = READ_ONCE(sbq->wake_batch);
-+
-       /*
-        * Wake up first in case that concurrent callers decrease wait_cnt
-        * while waitqueue is empty.
-        */
--      wake_up_nr(&ws->wait, max(wake_batch, nr));
-+      wake_up_nr(&ws->wait, wake_batch);
-       /*
-        * Pairs with the memory barrier in sbitmap_queue_resize() to
-@@ -656,11 +652,12 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq, int nr)
-       return false;
- }
--void sbitmap_queue_wake_up(struct sbitmap_queue *sbq, int nr)
-+void sbitmap_queue_wake_up(struct sbitmap_queue *sbq)
- {
--      while (__sbq_wake_up(sbq, nr))
-+      while (__sbq_wake_up(sbq))
-               ;
- }
-+EXPORT_SYMBOL_GPL(sbitmap_queue_wake_up);
- static inline void sbitmap_update_cpu_hint(struct sbitmap *sb, int cpu, int tag)
- {
-@@ -697,7 +694,7 @@ void sbitmap_queue_clear_batch(struct sbitmap_queue *sbq, int offset,
-               atomic_long_andnot(mask, (atomic_long_t *) addr);
-       smp_mb__after_atomic();
--      sbitmap_queue_wake_up(sbq, nr_tags);
-+      sbitmap_queue_wake_up(sbq);
-       sbitmap_update_cpu_hint(&sbq->sb, raw_smp_processor_id(),
-                                       tags[nr_tags - 1] - offset);
- }
-@@ -725,7 +722,7 @@ void sbitmap_queue_clear(struct sbitmap_queue *sbq, unsigned int nr,
-        * waiter. See the comment on waitqueue_active().
-        */
-       smp_mb__after_atomic();
--      sbitmap_queue_wake_up(sbq, 1);
-+      sbitmap_queue_wake_up(sbq);
-       sbitmap_update_cpu_hint(&sbq->sb, cpu, nr);
- }
- EXPORT_SYMBOL_GPL(sbitmap_queue_clear);
--- 
-2.35.1
-
diff --git a/queue-5.19/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch b/queue-5.19/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
deleted file mode 100644 (file)
index 4f6848f..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From c1fc79d079bd7a0ceec512ee7946ce8150c046ef Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 8 Sep 2022 15:09:37 +0200
-Subject: sbitmap: Avoid leaving waitqueue in invalid state in __sbq_wake_up()
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit 48c033314f372478548203c583529f53080fd078 ]
-
-When __sbq_wake_up() decrements wait_cnt to 0 but races with someone
-else waking the waiter on the waitqueue (so the waitqueue becomes
-empty), it exits without reseting wait_cnt to wake_batch number. Once
-wait_cnt is 0, nobody will ever reset the wait_cnt or wake the new
-waiters resulting in possible deadlocks or busyloops. Fix the problem by
-making sure we reset wait_cnt even if we didn't wake up anybody in the
-end.
-
-Fixes: 040b83fcecfb ("sbitmap: fix possible io hung due to lost wakeup")
-Reported-by: Keith Busch <kbusch@kernel.org>
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220908130937.2795-1-jack@suse.cz
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index 1f31147872e6..bb1970ad4875 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -605,6 +605,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       struct sbq_wait_state *ws;
-       unsigned int wake_batch;
-       int wait_cnt;
-+      bool ret;
-       ws = sbq_wake_ptr(sbq);
-       if (!ws)
-@@ -615,12 +616,23 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-        * For concurrent callers of this, callers should call this function
-        * again to wakeup a new batch on a different 'ws'.
-        */
--      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+      if (wait_cnt < 0)
-               return true;
-+      /*
-+       * If we decremented queue without waiters, retry to avoid lost
-+       * wakeups.
-+       */
-       if (wait_cnt > 0)
--              return false;
-+              return !waitqueue_active(&ws->wait);
-+      /*
-+       * When wait_cnt == 0, we have to be particularly careful as we are
-+       * responsible to reset wait_cnt regardless whether we've actually
-+       * woken up anybody. But in case we didn't wakeup anybody, we still
-+       * need to retry.
-+       */
-+      ret = !waitqueue_active(&ws->wait);
-       wake_batch = READ_ONCE(sbq->wake_batch);
-       /*
-@@ -649,7 +661,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       sbq_index_atomic_inc(&sbq->wake_index);
-       atomic_set(&ws->wait_cnt, wake_batch);
--      return false;
-+      return ret;
- }
- void sbitmap_queue_wake_up(struct sbitmap_queue *sbq)
--- 
-2.35.1
-
diff --git a/queue-5.19/sbitmap-fix-batched-wait_cnt-accounting.patch b/queue-5.19/sbitmap-fix-batched-wait_cnt-accounting.patch
deleted file mode 100644 (file)
index ebbeff6..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-From 3551abd659b4be2344b67cfd036151bd6c6363e2 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 25 Aug 2022 07:53:12 -0700
-Subject: sbitmap: fix batched wait_cnt accounting
-
-From: Keith Busch <kbusch@kernel.org>
-
-[ Upstream commit 16ede66973c84f890c03584f79158dd5b2d725f5 ]
-
-Batched completions can clear multiple bits, but we're only decrementing
-the wait_cnt by one each time. This can cause waiters to never be woken,
-stalling IO. Use the batched count instead.
-
-Link: https://bugzilla.kernel.org/show_bug.cgi?id=215679
-Signed-off-by: Keith Busch <kbusch@kernel.org>
-Link: https://lore.kernel.org/r/20220825145312.1217900-1-kbusch@fb.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Stable-dep-of: 48c033314f37 ("sbitmap: Avoid leaving waitqueue in invalid state in __sbq_wake_up()")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- block/blk-mq-tag.c      |  2 +-
- include/linux/sbitmap.h |  3 ++-
- lib/sbitmap.c           | 31 +++++++++++++++++--------------
- 3 files changed, 20 insertions(+), 16 deletions(-)
-
-diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
-index 2dcd738c6952..7aea93047caf 100644
---- a/block/blk-mq-tag.c
-+++ b/block/blk-mq-tag.c
-@@ -200,7 +200,7 @@ unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data)
-                * other allocations on previous queue won't be starved.
-                */
-               if (bt != bt_prev)
--                      sbitmap_queue_wake_up(bt_prev);
-+                      sbitmap_queue_wake_up(bt_prev, 1);
-               ws = bt_wait_ptr(bt, data->hctx);
-       } while (1);
-diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
-index 8f5a86e210b9..4d2d5205ab58 100644
---- a/include/linux/sbitmap.h
-+++ b/include/linux/sbitmap.h
-@@ -575,8 +575,9 @@ void sbitmap_queue_wake_all(struct sbitmap_queue *sbq);
-  * sbitmap_queue_wake_up() - Wake up some of waiters in one waitqueue
-  * on a &struct sbitmap_queue.
-  * @sbq: Bitmap queue to wake up.
-+ * @nr: Number of bits cleared.
-  */
--void sbitmap_queue_wake_up(struct sbitmap_queue *sbq);
-+void sbitmap_queue_wake_up(struct sbitmap_queue *sbq, int nr);
- /**
-  * sbitmap_queue_show() - Dump &struct sbitmap_queue information to a &struct
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index 1f31147872e6..a8aae1fc5206 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -600,34 +600,38 @@ static struct sbq_wait_state *sbq_wake_ptr(struct sbitmap_queue *sbq)
-       return NULL;
- }
--static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-+static bool __sbq_wake_up(struct sbitmap_queue *sbq, int nr)
- {
-       struct sbq_wait_state *ws;
--      unsigned int wake_batch;
--      int wait_cnt;
-+      int wake_batch, wait_cnt, cur;
-       ws = sbq_wake_ptr(sbq);
--      if (!ws)
-+      if (!ws || !nr)
-               return false;
--      wait_cnt = atomic_dec_return(&ws->wait_cnt);
-+      wake_batch = READ_ONCE(sbq->wake_batch);
-+      cur = atomic_read(&ws->wait_cnt);
-+      do {
-+              if (cur <= 0)
-+                      return true;
-+              wait_cnt = cur - nr;
-+      } while (!atomic_try_cmpxchg(&ws->wait_cnt, &cur, wait_cnt));
-+
-       /*
-        * For concurrent callers of this, callers should call this function
-        * again to wakeup a new batch on a different 'ws'.
-        */
--      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+      if (!waitqueue_active(&ws->wait))
-               return true;
-       if (wait_cnt > 0)
-               return false;
--      wake_batch = READ_ONCE(sbq->wake_batch);
--
-       /*
-        * Wake up first in case that concurrent callers decrease wait_cnt
-        * while waitqueue is empty.
-        */
--      wake_up_nr(&ws->wait, wake_batch);
-+      wake_up_nr(&ws->wait, max(wake_batch, nr));
-       /*
-        * Pairs with the memory barrier in sbitmap_queue_resize() to
-@@ -652,12 +656,11 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       return false;
- }
--void sbitmap_queue_wake_up(struct sbitmap_queue *sbq)
-+void sbitmap_queue_wake_up(struct sbitmap_queue *sbq, int nr)
- {
--      while (__sbq_wake_up(sbq))
-+      while (__sbq_wake_up(sbq, nr))
-               ;
- }
--EXPORT_SYMBOL_GPL(sbitmap_queue_wake_up);
- static inline void sbitmap_update_cpu_hint(struct sbitmap *sb, int cpu, int tag)
- {
-@@ -694,7 +697,7 @@ void sbitmap_queue_clear_batch(struct sbitmap_queue *sbq, int offset,
-               atomic_long_andnot(mask, (atomic_long_t *) addr);
-       smp_mb__after_atomic();
--      sbitmap_queue_wake_up(sbq);
-+      sbitmap_queue_wake_up(sbq, nr_tags);
-       sbitmap_update_cpu_hint(&sbq->sb, raw_smp_processor_id(),
-                                       tags[nr_tags - 1] - offset);
- }
-@@ -722,7 +725,7 @@ void sbitmap_queue_clear(struct sbitmap_queue *sbq, unsigned int nr,
-        * waiter. See the comment on waitqueue_active().
-        */
-       smp_mb__after_atomic();
--      sbitmap_queue_wake_up(sbq);
-+      sbitmap_queue_wake_up(sbq, 1);
-       sbitmap_update_cpu_hint(&sbq->sb, cpu, nr);
- }
- EXPORT_SYMBOL_GPL(sbitmap_queue_clear);
--- 
-2.35.1
-
diff --git a/queue-5.19/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch b/queue-5.19/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
deleted file mode 100644 (file)
index f743495..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-From 4cb065659e053366d6113a3526580558897ea8fc Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 3 Aug 2022 20:15:04 +0800
-Subject: sbitmap: fix possible io hung due to lost wakeup
-
-From: Yu Kuai <yukuai3@huawei.com>
-
-[ Upstream commit 040b83fcecfb86f3225d3a5de7fd9b3fbccf83b4 ]
-
-There are two problems can lead to lost wakeup:
-
-1) invalid wakeup on the wrong waitqueue:
-
-For example, 2 * wake_batch tags are put, while only wake_batch threads
-are woken:
-
-__sbq_wake_up
- atomic_cmpxchg -> reset wait_cnt
-                       __sbq_wake_up -> decrease wait_cnt
-                       ...
-                       __sbq_wake_up -> wait_cnt is decreased to 0 again
-                        atomic_cmpxchg
-                        sbq_index_atomic_inc -> increase wake_index
-                        wake_up_nr -> wake up and waitqueue might be empty
- sbq_index_atomic_inc -> increase again, one waitqueue is skipped
- wake_up_nr -> invalid wake up because old wakequeue might be empty
-
-To fix the problem, increasing 'wake_index' before resetting 'wait_cnt'.
-
-2) 'wait_cnt' can be decreased while waitqueue is empty
-
-As pointed out by Jan Kara, following race is possible:
-
-CPU1                           CPU2
-__sbq_wake_up                   __sbq_wake_up
- sbq_wake_ptr()                         sbq_wake_ptr() -> the same
- wait_cnt = atomic_dec_return()
- /* decreased to 0 */
- sbq_index_atomic_inc()
- /* move to next waitqueue */
- atomic_set()
- /* reset wait_cnt */
- wake_up_nr()
- /* wake up on the old waitqueue */
-                                wait_cnt = atomic_dec_return()
-                                /*
-                                 * decrease wait_cnt in the old
-                                 * waitqueue, while it can be
-                                 * empty.
-                                 */
-
-Fix the problem by waking up before updating 'wake_index' and
-'wait_cnt'.
-
-With this patch, noted that 'wait_cnt' is still decreased in the old
-empty waitqueue, however, the wakeup is redirected to a active waitqueue,
-and the extra decrement on the old empty waitqueue is not handled.
-
-Fixes: 88459642cba4 ("blk-mq: abstract tag allocation out into sbitmap library")
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Reviewed-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220803121504.212071-1-yukuai1@huaweicloud.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 55 ++++++++++++++++++++++++++++++---------------------
- 1 file changed, 33 insertions(+), 22 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index 29eb0484215a..1f31147872e6 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -611,32 +611,43 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-               return false;
-       wait_cnt = atomic_dec_return(&ws->wait_cnt);
--      if (wait_cnt <= 0) {
--              int ret;
-+      /*
-+       * For concurrent callers of this, callers should call this function
-+       * again to wakeup a new batch on a different 'ws'.
-+       */
-+      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+              return true;
--              wake_batch = READ_ONCE(sbq->wake_batch);
-+      if (wait_cnt > 0)
-+              return false;
--              /*
--               * Pairs with the memory barrier in sbitmap_queue_resize() to
--               * ensure that we see the batch size update before the wait
--               * count is reset.
--               */
--              smp_mb__before_atomic();
-+      wake_batch = READ_ONCE(sbq->wake_batch);
--              /*
--               * For concurrent callers of this, the one that failed the
--               * atomic_cmpxhcg() race should call this function again
--               * to wakeup a new batch on a different 'ws'.
--               */
--              ret = atomic_cmpxchg(&ws->wait_cnt, wait_cnt, wake_batch);
--              if (ret == wait_cnt) {
--                      sbq_index_atomic_inc(&sbq->wake_index);
--                      wake_up_nr(&ws->wait, wake_batch);
--                      return false;
--              }
-+      /*
-+       * Wake up first in case that concurrent callers decrease wait_cnt
-+       * while waitqueue is empty.
-+       */
-+      wake_up_nr(&ws->wait, wake_batch);
--              return true;
--      }
-+      /*
-+       * Pairs with the memory barrier in sbitmap_queue_resize() to
-+       * ensure that we see the batch size update before the wait
-+       * count is reset.
-+       *
-+       * Also pairs with the implicit barrier between decrementing wait_cnt
-+       * and checking for waitqueue_active() to make sure waitqueue_active()
-+       * sees result of the wakeup if atomic_dec_return() has seen the result
-+       * of atomic_set().
-+       */
-+      smp_mb__before_atomic();
-+
-+      /*
-+       * Increase wake_index before updating wait_cnt, otherwise concurrent
-+       * callers can see valid wait_cnt in old waitqueue, which can cause
-+       * invalid wakeup on the old waitqueue.
-+       */
-+      sbq_index_atomic_inc(&sbq->wake_index);
-+      atomic_set(&ws->wait_cnt, wake_batch);
-       return false;
- }
--- 
-2.35.1
-
index b5142f6bd225258c094e5fbc45afcf0cee0d89c0..60aaa7fc66009ce012658f4a0796d5ee83fd903d 100644 (file)
@@ -405,7 +405,6 @@ clk-tegra-fix-refcount-leak-in-tegra210_clock_init.patch
 clk-tegra-fix-refcount-leak-in-tegra114_clock_init.patch
 clk-tegra20-fix-refcount-leak-in-tegra20_clock_init.patch
 clk-samsung-exynosautov9-correct-register-offsets-of.patch
-sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
 hid-uclogic-make-template-placeholder-ids-generic.patch
 hid-uclogic-fix-warning-in-uclogic_rdesc_template_ap.patch
 hsi-omap_ssi-fix-refcount-leak-in-ssi_probe.patch
@@ -440,9 +439,6 @@ dyndbg-fix-static_branch-manipulation.patch
 dyndbg-fix-module.dyndbg-handling.patch
 dyndbg-let-query-modname-override-actual-module-name.patch
 dyndbg-drop-exported-dynamic_debug_exec_queries.patch
-sbitmap-fix-batched-wait_cnt-accounting.patch
-revert-sbitmap-fix-batched-wait_cnt-accounting.patch
-sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
 clk-qcom-sm6115-select-qcom_gdsc.patch
 scsi-lpfc-fix-various-issues-reported-by-tools.patch
 mtd-devices-docg3-check-the-return-value-of-devm_ior.patch
diff --git a/queue-5.4/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch b/queue-5.4/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
deleted file mode 100644 (file)
index 2d40697..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From 6edafbfeb613a3a163eaaff3d1f18bfcc189a627 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 8 Sep 2022 15:09:37 +0200
-Subject: sbitmap: Avoid leaving waitqueue in invalid state in __sbq_wake_up()
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit 48c033314f372478548203c583529f53080fd078 ]
-
-When __sbq_wake_up() decrements wait_cnt to 0 but races with someone
-else waking the waiter on the waitqueue (so the waitqueue becomes
-empty), it exits without reseting wait_cnt to wake_batch number. Once
-wait_cnt is 0, nobody will ever reset the wait_cnt or wake the new
-waiters resulting in possible deadlocks or busyloops. Fix the problem by
-making sure we reset wait_cnt even if we didn't wake up anybody in the
-end.
-
-Fixes: 040b83fcecfb ("sbitmap: fix possible io hung due to lost wakeup")
-Reported-by: Keith Busch <kbusch@kernel.org>
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220908130937.2795-1-jack@suse.cz
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index 7df295a15c3d..fe67d6da7156 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -530,6 +530,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       struct sbq_wait_state *ws;
-       unsigned int wake_batch;
-       int wait_cnt;
-+      bool ret;
-       ws = sbq_wake_ptr(sbq);
-       if (!ws)
-@@ -540,12 +541,23 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-        * For concurrent callers of this, callers should call this function
-        * again to wakeup a new batch on a different 'ws'.
-        */
--      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+      if (wait_cnt < 0)
-               return true;
-+      /*
-+       * If we decremented queue without waiters, retry to avoid lost
-+       * wakeups.
-+       */
-       if (wait_cnt > 0)
--              return false;
-+              return !waitqueue_active(&ws->wait);
-+      /*
-+       * When wait_cnt == 0, we have to be particularly careful as we are
-+       * responsible to reset wait_cnt regardless whether we've actually
-+       * woken up anybody. But in case we didn't wakeup anybody, we still
-+       * need to retry.
-+       */
-+      ret = !waitqueue_active(&ws->wait);
-       wake_batch = READ_ONCE(sbq->wake_batch);
-       /*
-@@ -574,7 +586,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       sbq_index_atomic_inc(&sbq->wake_index);
-       atomic_set(&ws->wait_cnt, wake_batch);
--      return false;
-+      return ret;
- }
- void sbitmap_queue_wake_up(struct sbitmap_queue *sbq)
--- 
-2.35.1
-
diff --git a/queue-5.4/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch b/queue-5.4/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
deleted file mode 100644 (file)
index 3e01ae8..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-From dcef8b05380b764e2ab4cd87bc9b5472dc3ee5f8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 3 Aug 2022 20:15:04 +0800
-Subject: sbitmap: fix possible io hung due to lost wakeup
-
-From: Yu Kuai <yukuai3@huawei.com>
-
-[ Upstream commit 040b83fcecfb86f3225d3a5de7fd9b3fbccf83b4 ]
-
-There are two problems can lead to lost wakeup:
-
-1) invalid wakeup on the wrong waitqueue:
-
-For example, 2 * wake_batch tags are put, while only wake_batch threads
-are woken:
-
-__sbq_wake_up
- atomic_cmpxchg -> reset wait_cnt
-                       __sbq_wake_up -> decrease wait_cnt
-                       ...
-                       __sbq_wake_up -> wait_cnt is decreased to 0 again
-                        atomic_cmpxchg
-                        sbq_index_atomic_inc -> increase wake_index
-                        wake_up_nr -> wake up and waitqueue might be empty
- sbq_index_atomic_inc -> increase again, one waitqueue is skipped
- wake_up_nr -> invalid wake up because old wakequeue might be empty
-
-To fix the problem, increasing 'wake_index' before resetting 'wait_cnt'.
-
-2) 'wait_cnt' can be decreased while waitqueue is empty
-
-As pointed out by Jan Kara, following race is possible:
-
-CPU1                           CPU2
-__sbq_wake_up                   __sbq_wake_up
- sbq_wake_ptr()                         sbq_wake_ptr() -> the same
- wait_cnt = atomic_dec_return()
- /* decreased to 0 */
- sbq_index_atomic_inc()
- /* move to next waitqueue */
- atomic_set()
- /* reset wait_cnt */
- wake_up_nr()
- /* wake up on the old waitqueue */
-                                wait_cnt = atomic_dec_return()
-                                /*
-                                 * decrease wait_cnt in the old
-                                 * waitqueue, while it can be
-                                 * empty.
-                                 */
-
-Fix the problem by waking up before updating 'wake_index' and
-'wait_cnt'.
-
-With this patch, noted that 'wait_cnt' is still decreased in the old
-empty waitqueue, however, the wakeup is redirected to a active waitqueue,
-and the extra decrement on the old empty waitqueue is not handled.
-
-Fixes: 88459642cba4 ("blk-mq: abstract tag allocation out into sbitmap library")
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Reviewed-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220803121504.212071-1-yukuai1@huaweicloud.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 55 ++++++++++++++++++++++++++++++---------------------
- 1 file changed, 33 insertions(+), 22 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index ee3ce1494568..7df295a15c3d 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -536,32 +536,43 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-               return false;
-       wait_cnt = atomic_dec_return(&ws->wait_cnt);
--      if (wait_cnt <= 0) {
--              int ret;
-+      /*
-+       * For concurrent callers of this, callers should call this function
-+       * again to wakeup a new batch on a different 'ws'.
-+       */
-+      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+              return true;
--              wake_batch = READ_ONCE(sbq->wake_batch);
-+      if (wait_cnt > 0)
-+              return false;
--              /*
--               * Pairs with the memory barrier in sbitmap_queue_resize() to
--               * ensure that we see the batch size update before the wait
--               * count is reset.
--               */
--              smp_mb__before_atomic();
-+      wake_batch = READ_ONCE(sbq->wake_batch);
--              /*
--               * For concurrent callers of this, the one that failed the
--               * atomic_cmpxhcg() race should call this function again
--               * to wakeup a new batch on a different 'ws'.
--               */
--              ret = atomic_cmpxchg(&ws->wait_cnt, wait_cnt, wake_batch);
--              if (ret == wait_cnt) {
--                      sbq_index_atomic_inc(&sbq->wake_index);
--                      wake_up_nr(&ws->wait, wake_batch);
--                      return false;
--              }
-+      /*
-+       * Wake up first in case that concurrent callers decrease wait_cnt
-+       * while waitqueue is empty.
-+       */
-+      wake_up_nr(&ws->wait, wake_batch);
--              return true;
--      }
-+      /*
-+       * Pairs with the memory barrier in sbitmap_queue_resize() to
-+       * ensure that we see the batch size update before the wait
-+       * count is reset.
-+       *
-+       * Also pairs with the implicit barrier between decrementing wait_cnt
-+       * and checking for waitqueue_active() to make sure waitqueue_active()
-+       * sees result of the wakeup if atomic_dec_return() has seen the result
-+       * of atomic_set().
-+       */
-+      smp_mb__before_atomic();
-+
-+      /*
-+       * Increase wake_index before updating wait_cnt, otherwise concurrent
-+       * callers can see valid wait_cnt in old waitqueue, which can cause
-+       * invalid wakeup on the old waitqueue.
-+       */
-+      sbq_index_atomic_inc(&sbq->wake_index);
-+      atomic_set(&ws->wait_cnt, wake_batch);
-       return false;
- }
--- 
-2.35.1
-
index 966186c5f6d635e4176c52a368c66f9a39672dff..1e445ca9882365145d79513976cc3e6732c17309 100644 (file)
@@ -127,7 +127,6 @@ clk-berlin-add-of_node_put-for-of_get_parent.patch
 clk-tegra-fix-refcount-leak-in-tegra210_clock_init.patch
 clk-tegra-fix-refcount-leak-in-tegra114_clock_init.patch
 clk-tegra20-fix-refcount-leak-in-tegra20_clock_init.patch
-sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
 hsi-omap_ssi-fix-refcount-leak-in-ssi_probe.patch
 hsi-omap_ssi_port-fix-dma_map_sg-error-check.patch
 media-exynos4-is-fimc-is-add-of_node_put-when-breaki.patch
@@ -138,7 +137,6 @@ rdma-rxe-fix-the-error-caused-by-qp-sk.patch
 misc-ocxl-fix-possible-refcount-leak-in-afu_ioctl.patch
 dyndbg-fix-module.dyndbg-handling.patch
 dyndbg-let-query-modname-override-actual-module-name.patch
-sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
 mtd-devices-docg3-check-the-return-value-of-devm_ior.patch
 rdma-siw-always-consume-all-skbuf-data-in-sk_data_re.patch
 ata-fix-ata_id_sense_reporting_enabled-and-ata_id_ha.patch
diff --git a/queue-6.0/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch b/queue-6.0/sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
deleted file mode 100644 (file)
index bbb0fa0..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From 67e50b0c78052157df4c79c8ba8ad177ca45f0a9 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 8 Sep 2022 15:09:37 +0200
-Subject: sbitmap: Avoid leaving waitqueue in invalid state in __sbq_wake_up()
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit 48c033314f372478548203c583529f53080fd078 ]
-
-When __sbq_wake_up() decrements wait_cnt to 0 but races with someone
-else waking the waiter on the waitqueue (so the waitqueue becomes
-empty), it exits without reseting wait_cnt to wake_batch number. Once
-wait_cnt is 0, nobody will ever reset the wait_cnt or wake the new
-waiters resulting in possible deadlocks or busyloops. Fix the problem by
-making sure we reset wait_cnt even if we didn't wake up anybody in the
-end.
-
-Fixes: 040b83fcecfb ("sbitmap: fix possible io hung due to lost wakeup")
-Reported-by: Keith Busch <kbusch@kernel.org>
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220908130937.2795-1-jack@suse.cz
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index 1f31147872e6..bb1970ad4875 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -605,6 +605,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       struct sbq_wait_state *ws;
-       unsigned int wake_batch;
-       int wait_cnt;
-+      bool ret;
-       ws = sbq_wake_ptr(sbq);
-       if (!ws)
-@@ -615,12 +616,23 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-        * For concurrent callers of this, callers should call this function
-        * again to wakeup a new batch on a different 'ws'.
-        */
--      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+      if (wait_cnt < 0)
-               return true;
-+      /*
-+       * If we decremented queue without waiters, retry to avoid lost
-+       * wakeups.
-+       */
-       if (wait_cnt > 0)
--              return false;
-+              return !waitqueue_active(&ws->wait);
-+      /*
-+       * When wait_cnt == 0, we have to be particularly careful as we are
-+       * responsible to reset wait_cnt regardless whether we've actually
-+       * woken up anybody. But in case we didn't wakeup anybody, we still
-+       * need to retry.
-+       */
-+      ret = !waitqueue_active(&ws->wait);
-       wake_batch = READ_ONCE(sbq->wake_batch);
-       /*
-@@ -649,7 +661,7 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-       sbq_index_atomic_inc(&sbq->wake_index);
-       atomic_set(&ws->wait_cnt, wake_batch);
--      return false;
-+      return ret;
- }
- void sbitmap_queue_wake_up(struct sbitmap_queue *sbq)
--- 
-2.35.1
-
diff --git a/queue-6.0/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch b/queue-6.0/sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
deleted file mode 100644 (file)
index 86216b7..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-From 6a6fe39fb947ccbe768f23442c2bf11596c4e1dc Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 3 Aug 2022 20:15:04 +0800
-Subject: sbitmap: fix possible io hung due to lost wakeup
-
-From: Yu Kuai <yukuai3@huawei.com>
-
-[ Upstream commit 040b83fcecfb86f3225d3a5de7fd9b3fbccf83b4 ]
-
-There are two problems can lead to lost wakeup:
-
-1) invalid wakeup on the wrong waitqueue:
-
-For example, 2 * wake_batch tags are put, while only wake_batch threads
-are woken:
-
-__sbq_wake_up
- atomic_cmpxchg -> reset wait_cnt
-                       __sbq_wake_up -> decrease wait_cnt
-                       ...
-                       __sbq_wake_up -> wait_cnt is decreased to 0 again
-                        atomic_cmpxchg
-                        sbq_index_atomic_inc -> increase wake_index
-                        wake_up_nr -> wake up and waitqueue might be empty
- sbq_index_atomic_inc -> increase again, one waitqueue is skipped
- wake_up_nr -> invalid wake up because old wakequeue might be empty
-
-To fix the problem, increasing 'wake_index' before resetting 'wait_cnt'.
-
-2) 'wait_cnt' can be decreased while waitqueue is empty
-
-As pointed out by Jan Kara, following race is possible:
-
-CPU1                           CPU2
-__sbq_wake_up                   __sbq_wake_up
- sbq_wake_ptr()                         sbq_wake_ptr() -> the same
- wait_cnt = atomic_dec_return()
- /* decreased to 0 */
- sbq_index_atomic_inc()
- /* move to next waitqueue */
- atomic_set()
- /* reset wait_cnt */
- wake_up_nr()
- /* wake up on the old waitqueue */
-                                wait_cnt = atomic_dec_return()
-                                /*
-                                 * decrease wait_cnt in the old
-                                 * waitqueue, while it can be
-                                 * empty.
-                                 */
-
-Fix the problem by waking up before updating 'wake_index' and
-'wait_cnt'.
-
-With this patch, noted that 'wait_cnt' is still decreased in the old
-empty waitqueue, however, the wakeup is redirected to a active waitqueue,
-and the extra decrement on the old empty waitqueue is not handled.
-
-Fixes: 88459642cba4 ("blk-mq: abstract tag allocation out into sbitmap library")
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Reviewed-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220803121504.212071-1-yukuai1@huaweicloud.com
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- lib/sbitmap.c | 55 ++++++++++++++++++++++++++++++---------------------
- 1 file changed, 33 insertions(+), 22 deletions(-)
-
-diff --git a/lib/sbitmap.c b/lib/sbitmap.c
-index 29eb0484215a..1f31147872e6 100644
---- a/lib/sbitmap.c
-+++ b/lib/sbitmap.c
-@@ -611,32 +611,43 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq)
-               return false;
-       wait_cnt = atomic_dec_return(&ws->wait_cnt);
--      if (wait_cnt <= 0) {
--              int ret;
-+      /*
-+       * For concurrent callers of this, callers should call this function
-+       * again to wakeup a new batch on a different 'ws'.
-+       */
-+      if (wait_cnt < 0 || !waitqueue_active(&ws->wait))
-+              return true;
--              wake_batch = READ_ONCE(sbq->wake_batch);
-+      if (wait_cnt > 0)
-+              return false;
--              /*
--               * Pairs with the memory barrier in sbitmap_queue_resize() to
--               * ensure that we see the batch size update before the wait
--               * count is reset.
--               */
--              smp_mb__before_atomic();
-+      wake_batch = READ_ONCE(sbq->wake_batch);
--              /*
--               * For concurrent callers of this, the one that failed the
--               * atomic_cmpxhcg() race should call this function again
--               * to wakeup a new batch on a different 'ws'.
--               */
--              ret = atomic_cmpxchg(&ws->wait_cnt, wait_cnt, wake_batch);
--              if (ret == wait_cnt) {
--                      sbq_index_atomic_inc(&sbq->wake_index);
--                      wake_up_nr(&ws->wait, wake_batch);
--                      return false;
--              }
-+      /*
-+       * Wake up first in case that concurrent callers decrease wait_cnt
-+       * while waitqueue is empty.
-+       */
-+      wake_up_nr(&ws->wait, wake_batch);
--              return true;
--      }
-+      /*
-+       * Pairs with the memory barrier in sbitmap_queue_resize() to
-+       * ensure that we see the batch size update before the wait
-+       * count is reset.
-+       *
-+       * Also pairs with the implicit barrier between decrementing wait_cnt
-+       * and checking for waitqueue_active() to make sure waitqueue_active()
-+       * sees result of the wakeup if atomic_dec_return() has seen the result
-+       * of atomic_set().
-+       */
-+      smp_mb__before_atomic();
-+
-+      /*
-+       * Increase wake_index before updating wait_cnt, otherwise concurrent
-+       * callers can see valid wait_cnt in old waitqueue, which can cause
-+       * invalid wakeup on the old waitqueue.
-+       */
-+      sbq_index_atomic_inc(&sbq->wake_index);
-+      atomic_set(&ws->wait_cnt, wake_batch);
-       return false;
- }
--- 
-2.35.1
-
index acb56eeb883b734fb29f420bb5ade5ef66963b01..9724780b05eb0a3a7ab2b0d2956f8211be936b8d 100644 (file)
@@ -475,7 +475,6 @@ clk-tegra-fix-refcount-leak-in-tegra210_clock_init.patch
 clk-tegra-fix-refcount-leak-in-tegra114_clock_init.patch
 clk-tegra20-fix-refcount-leak-in-tegra20_clock_init.patch
 clk-samsung-exynosautov9-correct-register-offsets-of.patch
-sbitmap-fix-possible-io-hung-due-to-lost-wakeup.patch
 hid-uclogic-add-missing-suffix-for-digitalizers.patch
 hid-uclogic-fix-warning-in-uclogic_rdesc_template_ap.patch
 hsi-omap_ssi-fix-refcount-leak-in-ssi_probe.patch
@@ -513,7 +512,6 @@ dyndbg-fix-static_branch-manipulation.patch
 dyndbg-fix-module.dyndbg-handling.patch
 dyndbg-let-query-modname-override-actual-module-name.patch
 dyndbg-drop-exported-dynamic_debug_exec_queries.patch
-sbitmap-avoid-leaving-waitqueue-in-invalid-state-in-.patch
 clk-qcom-sm6115-select-qcom_gdsc.patch
 scsi-lpfc-fix-various-issues-reported-by-tools.patch
 mtd-devices-docg3-check-the-return-value-of-devm_ior.patch