+++ /dev/null
-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
-
+++ /dev/null
-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
-
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
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
+++ /dev/null
-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
-
+++ /dev/null
-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
-
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
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
+++ /dev/null
-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
-
+++ /dev/null
-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
-
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
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
+++ /dev/null
-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
-
+++ /dev/null
-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
-
+++ /dev/null
-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
-
+++ /dev/null
-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
-
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
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
+++ /dev/null
-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
-
+++ /dev/null
-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
-
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
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
+++ /dev/null
-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
-
+++ /dev/null
-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
-
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
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