mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00
blk-mq: fix lockdep warning in __blk_mq_update_nr_hw_queues
[ Upstream commit 2d82f3bd8910eb65e30bb2a3c9b945bfb3b6d661 ] Commit5989bfe6ac
("block: restore two stage elevator switch while running nr_hw_queue update") reintroduced a lockdep warning by calling blk_mq_freeze_queue_nomemsave() before switching the I/O scheduler. The function blk_mq_elv_switch_none() calls elevator_change_done(). Running this while the queue is frozen causes a lockdep warning. Fix this by reordering the operations: first, switch the I/O scheduler to 'none', and then freeze the queue. This ensures that elevator_change_done() is not called on an already frozen queue. And this way is safe because elevator_set_none() does freeze queue before switching to none. Also we still have to rely on blk_mq_elv_switch_back() for switching back, and it has to cover unfrozen queue case. Cc: Nilay Shroff <nilay@linux.ibm.com> Cc: Yu Kuai <yukuai3@huawei.com> Fixes:5989bfe6ac
("block: restore two stage elevator switch while running nr_hw_queue update") Signed-off-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Yu Kuai <yukuai3@huawei.com> Reviewed-by: Nilay Shroff <nilay@linux.ibm.com> Link: https://lore.kernel.org/r/20250815131737.331692-1-ming.lei@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
e01facfb54
commit
f9a9098ca8
|
@ -5031,6 +5031,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
|
|||
unsigned int memflags;
|
||||
int i;
|
||||
struct xarray elv_tbl, et_tbl;
|
||||
bool queues_frozen = false;
|
||||
|
||||
lockdep_assert_held(&set->tag_list_lock);
|
||||
|
||||
|
@ -5054,9 +5055,6 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
|
|||
blk_mq_sysfs_unregister_hctxs(q);
|
||||
}
|
||||
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list)
|
||||
blk_mq_freeze_queue_nomemsave(q);
|
||||
|
||||
/*
|
||||
* Switch IO scheduler to 'none', cleaning up the data associated
|
||||
* with the previous scheduler. We will switch back once we are done
|
||||
|
@ -5066,6 +5064,9 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
|
|||
if (blk_mq_elv_switch_none(q, &elv_tbl))
|
||||
goto switch_back;
|
||||
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list)
|
||||
blk_mq_freeze_queue_nomemsave(q);
|
||||
queues_frozen = true;
|
||||
if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0)
|
||||
goto switch_back;
|
||||
|
||||
|
@ -5089,8 +5090,12 @@ fallback:
|
|||
}
|
||||
switch_back:
|
||||
/* The blk_mq_elv_switch_back unfreezes queue for us. */
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list)
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list) {
|
||||
/* switch_back expects queue to be frozen */
|
||||
if (!queues_frozen)
|
||||
blk_mq_freeze_queue_nomemsave(q);
|
||||
blk_mq_elv_switch_back(q, &elv_tbl, &et_tbl);
|
||||
}
|
||||
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list) {
|
||||
blk_mq_sysfs_register_hctxs(q);
|
||||
|
|
Loading…
Reference in New Issue
Block a user