From: Kemeng Shi shikemeng@huaweicloud.com
mainline inclusion from mainline-v6.3-rc1 commit 47df9ce95cd568d3f84218c4f65e9fbd4dfeda55 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAQPKU CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
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 Conflicts: block/blk-mq.c [commit 2a5a24aa8338 ("scsi: blk-mq: Return budget token from .get_budget callback") and commit 079a2e3e8625 ("blk-mq: Change shared sbitmap naming to shared tags") are not backported] Signed-off-by: Yu Kuai yukuai3@huawei.com --- block/blk-mq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c index 22926a9a5651..d6694b65e02f 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1241,7 +1241,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_sbitmap_shared(hctx->flags))) { blk_mq_sched_mark_restart_hctx(hctx);
/* @@ -1520,7 +1521,8 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list, 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_sbitmap_shared(hctx->flags));
blk_mq_release_budgets(q, nr_budgets);