mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
block: fix potential deadlock while running nr_hw_queue update
Move scheduler tags (sched_tags) allocation and deallocation outside both the ->elevator_lock and ->freeze_lock when updating nr_hw_queues. This change breaks the dependency chain from the percpu allocator lock to the elevator lock, helping to prevent potential deadlocks, as observed in the reported lockdep splat[1]. This commit introduces batch allocation and deallocation helpers for sched_tags, which are now used from within __blk_mq_update_nr_hw_queues routine while iterating through the tagset. With this change, all sched_tags memory management is handled entirely outside the ->elevator_lock and the ->freeze_lock context, thereby eliminating the lock dependency that could otherwise manifest during nr_hw_queues updates. [1] https://lore.kernel.org/all/0659ea8d-a463-47c8-9180-43c719e106eb@linux.ibm.com/ Reported-by: Stefan Haberland <sth@linux.ibm.com> Closes: https://lore.kernel.org/all/0659ea8d-a463-47c8-9180-43c719e106eb@linux.ibm.com/ Reviewed-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Nilay Shroff <nilay@linux.ibm.com> Link: https://lore.kernel.org/r/20250730074614.2537382-4-nilay@linux.ibm.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include "blk-crypto-internal.h"
|
||||
|
||||
struct elevator_type;
|
||||
struct elevator_tags;
|
||||
|
||||
/*
|
||||
* Default upper limit for the software max_sectors limit used for regular I/Os.
|
||||
@@ -330,7 +331,8 @@ bool blk_bio_list_merge(struct request_queue *q, struct list_head *list,
|
||||
|
||||
bool blk_insert_flush(struct request *rq);
|
||||
|
||||
void elv_update_nr_hw_queues(struct request_queue *q, struct elevator_type *e);
|
||||
void elv_update_nr_hw_queues(struct request_queue *q, struct elevator_type *e,
|
||||
struct elevator_tags *t);
|
||||
void elevator_set_default(struct request_queue *q);
|
||||
void elevator_set_none(struct request_queue *q);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user