blk-mq: Fix potential io hung for shared sbitmap per tagset
authorKemeng Shi <shikemeng@huaweicloud.com>
Wed, 18 Jan 2023 09:37:16 +0000 (17:37 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 Mar 2023 08:32:44 +0000 (09:32 +0100)
[ Upstream commit 47df9ce95cd568d3f84218c4f65e9fbd4dfeda55 ]

Commit f906a6a0f4268 ("blk-mq: improve tag waiting setup for non-shared
tags") mark restart for unshared tags for improvement. At that time,
tags is only shared betweens queues and we can check if tags is shared
by test BLK_MQ_F_TAG_SHARED.
Afterwards, commit 32bc15afed04b ("blk-mq: Facilitate a shared sbitmap per
tagset") enabled tags share betweens hctxs inside a queue. We only
mark restart for shared hctxs inside a queue and may cause io hung if
there is no tag currently allocated by hctxs going to be marked restart.
Wait on sbitmap_queue instead of mark restart for shared hctxs case to
fix this.

Fixes: 32bc15afed04 ("blk-mq: Facilitate a shared sbitmap per tagset")
Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
block/blk-mq.c

index faffc64..fe0a3a8 100644 (file)
@@ -1799,7 +1799,8 @@ static bool blk_mq_mark_tag_wait(struct blk_mq_hw_ctx *hctx,
        wait_queue_entry_t *wait;
        bool ret;
 
-       if (!(hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED)) {
+       if (!(hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED) &&
+           !(blk_mq_is_shared_tags(hctx->flags))) {
                blk_mq_sched_mark_restart_hctx(hctx);
 
                /*
@@ -2069,7 +2070,8 @@ out:
                bool needs_restart;
                /* For non-shared tags, the RESTART check will suffice */
                bool no_tag = prep == PREP_DISPATCH_NO_TAG &&
-                       (hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED);
+                       ((hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED) ||
+                       blk_mq_is_shared_tags(hctx->flags));
 
                if (nr_budgets)
                        blk_mq_release_budgets(q, list);