UPSTREAM: nvme: fix queue freeze vs limits lock order
Match the locking order used by the core block code by only freezing the queue after taking the limits lock. Unlike most queue updates this does not use the queue_limits_commit_update_frozen helper as the nvme driver want the queue frozen for more than just the limits update. Change-Id: I85186767edc57eb14287122dda5aaafbfa7aa0c5 Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Nilay Shroff <nilay@linux.ibm.com> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Link: https://lore.kernel.org/r/20250110054726.1499538-8-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk> (cherry picked from commit 473106dd3aa964a62314d858f6602c95e40e6270) Signed-off-by: Bart Van Assche <bvanassche@google.com>
This commit is contained in:
committed by
Bart Van Assche
parent
32ab5e2dd9
commit
1bf8be0b4e
@@ -2128,9 +2128,10 @@ static int nvme_update_ns_info_generic(struct nvme_ns *ns,
|
||||
struct queue_limits lim;
|
||||
int ret;
|
||||
|
||||
blk_mq_freeze_queue(ns->disk->queue);
|
||||
lim = queue_limits_start_update(ns->disk->queue);
|
||||
nvme_set_ctrl_limits(ns->ctrl, &lim);
|
||||
|
||||
blk_mq_freeze_queue(ns->disk->queue);
|
||||
ret = queue_limits_commit_update(ns->disk->queue, &lim);
|
||||
set_disk_ro(ns->disk, nvme_ns_is_readonly(ns, info));
|
||||
blk_mq_unfreeze_queue(ns->disk->queue);
|
||||
@@ -2177,12 +2178,12 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
|
||||
goto out;
|
||||
}
|
||||
|
||||
lim = queue_limits_start_update(ns->disk->queue);
|
||||
|
||||
blk_mq_freeze_queue(ns->disk->queue);
|
||||
ns->head->lba_shift = id->lbaf[lbaf].ds;
|
||||
ns->head->nuse = le64_to_cpu(id->nuse);
|
||||
capacity = nvme_lba_to_sect(ns->head, le64_to_cpu(id->nsze));
|
||||
|
||||
lim = queue_limits_start_update(ns->disk->queue);
|
||||
nvme_set_ctrl_limits(ns->ctrl, &lim);
|
||||
nvme_configure_metadata(ns->ctrl, ns->head, id, nvm, info);
|
||||
nvme_set_chunk_sectors(ns, id, &lim);
|
||||
@@ -2282,6 +2283,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
|
||||
struct queue_limits *ns_lim = &ns->disk->queue->limits;
|
||||
struct queue_limits lim;
|
||||
|
||||
lim = queue_limits_start_update(ns->head->disk->queue);
|
||||
blk_mq_freeze_queue(ns->head->disk->queue);
|
||||
/*
|
||||
* queue_limits mixes values that are the hardware limitations
|
||||
@@ -2298,7 +2300,6 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
|
||||
* the splitting limits in to make sure we still obey possibly
|
||||
* lower limitations of other controllers.
|
||||
*/
|
||||
lim = queue_limits_start_update(ns->head->disk->queue);
|
||||
lim.logical_block_size = ns_lim->logical_block_size;
|
||||
lim.physical_block_size = ns_lim->physical_block_size;
|
||||
lim.io_min = ns_lim->io_min;
|
||||
|
||||
Reference in New Issue
Block a user