From: Ming Lei ming.lei@redhat.com
mainline inclusion from mainline-v5.15-rc6 commit b4459b11e840 category: panic bugzilla: 185513 https://gitee.com/openeuler/kernel/issues/I4V82O?from=project-issue CVE: NA
-------------------------------------------------
DM uses blk-mq's quiesce/unquiesce to stop/start device mapper queue.
But blk-mq's unquiesce may come from outside events, such as elevator switch, updating nr_requests or others, and request may come during suspend, so simply ask for blk-mq to requeue it.
Fixes one kernel panic issue when running updating nr_requests and dm-mpath suspend/resume stress test.
Cc: stable@vger.kernel.org Signed-off-by: Ming Lei ming.lei@redhat.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Luo Meng luomeng12@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/md/dm-core.h | 13 +++++++++++++ drivers/md/dm-rq.c | 8 ++++++++ drivers/md/dm.c | 13 ------------- 3 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h index 3db92d9a030b..595e87e03d43 100644 --- a/drivers/md/dm-core.h +++ b/drivers/md/dm-core.h @@ -122,6 +122,19 @@ struct mapped_device { struct srcu_struct io_barrier; };
+/* + * Bits for the flags field of struct mapped_device. + */ +#define DMF_BLOCK_IO_FOR_SUSPEND 0 +#define DMF_SUSPENDED 1 +#define DMF_FROZEN 2 +#define DMF_FREEING 3 +#define DMF_DELETING 4 +#define DMF_NOFLUSH_SUSPENDING 5 +#define DMF_DEFERRED_REMOVE 6 +#define DMF_SUSPENDED_INTERNALLY 7 +#define DMF_POST_SUSPENDING 8 + void disable_discard(struct mapped_device *md); void disable_write_same(struct mapped_device *md); void disable_write_zeroes(struct mapped_device *md); diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c index be708b7c66a1..a75929b222a4 100644 --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c @@ -490,6 +490,14 @@ static blk_status_t dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx, struct mapped_device *md = tio->md; struct dm_target *ti = md->immutable_target;
+ /* + * blk-mq's unquiesce may come from outside events, such as + * elevator switch, updating nr_requests or others, and request may + * come during suspend, so simply ask for blk-mq to requeue it. + */ + if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) + return BLK_STS_RESOURCE; + if (unlikely(!ti)) { int srcu_idx; struct dm_table *map; diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 2cc3419b4889..0f8e669f0de3 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -132,19 +132,6 @@ EXPORT_SYMBOL_GPL(dm_bio_get_target_bio_nr);
#define MINOR_ALLOCED ((void *)-1)
-/* - * Bits for the md->flags field. - */ -#define DMF_BLOCK_IO_FOR_SUSPEND 0 -#define DMF_SUSPENDED 1 -#define DMF_FROZEN 2 -#define DMF_FREEING 3 -#define DMF_DELETING 4 -#define DMF_NOFLUSH_SUSPENDING 5 -#define DMF_DEFERRED_REMOVE 6 -#define DMF_SUSPENDED_INTERNALLY 7 -#define DMF_POST_SUSPENDING 8 - #define DM_NUMA_NODE NUMA_NO_NODE static int dm_numa_node = DM_NUMA_NODE;