From: Keith Busch <kbusch@xxxxxxxxxx> The bitmap wait state may have set an active count, but doesn't have an active waiter due to racing with adding it. If that happens, the state's wait_cnt will be set at the wrong value, and could prevent future wakes until the atomic_dec wraps back to 0. Check the waitqueue_active before decrementing so that we don't need to account for fixing it up after. Fixes: 040b83fcecfb8 ("sbitmap: fix possible io hung due to lost wakeup") Signed-off-by: Keith Busch <kbusch@xxxxxxxxxx> --- lib/sbitmap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/sbitmap.c b/lib/sbitmap.c index a39b1a877366..ad0670b580d3 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c @@ -609,12 +609,16 @@ static bool __sbq_wake_up(struct sbitmap_queue *sbq) if (!ws) return false; + if (!waitqueue_active(&ws->wait)) + return true; + 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 (wait_cnt < 0 || !waitqueue_active(&ws->wait)) + if (wait_cnt < 0) return true; if (wait_cnt > 0) -- 2.30.2