Commit 65267b13 authored by Kemeng Shi's avatar Kemeng Shi Committed by Yu Kuai
Browse files

blk-mq: Fix potential io hung for shared sbitmap per tagset

mainline inclusion
from mainline-v6.3-rc1
commit 47df9ce9
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/?id=47df9ce95cd568d3f84218c4f65e9fbd4dfeda55



--------------------------------

Commit f906a6a0 ("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 32bc15af ("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: 32bc15af ("blk-mq: Facilitate a shared sbitmap per tagset")
Signed-off-by: default avatarKemeng Shi <shikemeng@huaweicloud.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
Conflicts:
	block/blk-mq.c
[commit 2a5a24aa ("scsi: blk-mq: Return budget token from .get_budget
callback") and commit 079a2e3e ("blk-mq: Change shared sbitmap naming
to shared tags") are not backported]
Signed-off-by: default avatarYu Kuai <yukuai3@huawei.com>
parent fba8b302
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -1245,7 +1245,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);

		/*
@@ -1524,7 +1525,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);