summaryrefslogtreecommitdiffstats
path: root/block/genhd.c
diff options
context:
space:
mode:
authorMing Lei <ming.lei@redhat.com>2022-03-08 06:51:58 +0100
committerJens Axboe <axboe@kernel.dk>2022-03-08 19:40:01 -0700
commit28ce942fa2d5d80af5367ba9d39f2e0b4af37bfd (patch)
tree54144a4404ef73f36491f095028bc15f7d0b5902 /block/genhd.c
parentba3e845665fbbb0252336f27200cd5cf288a3573 (diff)
block: move blk_exit_queue into disk_release
There can't be file system I/O in disk_release(), so move the call to blk_exit_queue() there, preparing to have the teardown of file system I/O only functionality in one place, when the gendisk that is needed for it is torn down. We still need to freeze queue here since the request is freed after the bio is completed and passthrough request rely on scheduler tags as well. The disk can be released before or after queue is cleaned up, and we have to free the scheduler request pool before blk_cleanup_queue returns, while the static request pool has to be freed before exiting the I/O scheduler. Signed-off-by: Ming Lei <ming.lei@redhat.com> [hch: rebased, updated the commit log] Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Link: https://lore.kernel.org/r/20220308055200.735835-13-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/genhd.c')
-rw-r--r--block/genhd.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/block/genhd.c b/block/genhd.c
index fc10aedab209..73705a749ea9 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1098,6 +1098,34 @@ static const struct attribute_group *disk_attr_groups[] = {
NULL
};
+static void disk_release_mq(struct request_queue *q)
+{
+ blk_mq_cancel_work_sync(q);
+
+ /*
+ * There can't be any non non-passthrough bios in flight here, but
+ * requests stay around longer, including passthrough ones so we
+ * still need to freeze the queue here.
+ */
+ blk_mq_freeze_queue(q);
+
+ /*
+ * Since the I/O scheduler exit code may access cgroup information,
+ * perform I/O scheduler exit before disassociating from the block
+ * cgroup controller.
+ */
+ if (q->elevator) {
+ ioc_clear_queue(q);
+
+ mutex_lock(&q->sysfs_lock);
+ blk_mq_sched_free_rqs(q);
+ elevator_exit(q);
+ mutex_unlock(&q->sysfs_lock);
+ }
+
+ __blk_mq_unfreeze_queue(q, true);
+}
+
/**
* disk_release - releases all allocated resources of the gendisk
* @dev: the device representing this disk
@@ -1119,7 +1147,8 @@ static void disk_release(struct device *dev)
might_sleep();
WARN_ON_ONCE(disk_live(disk));
- blk_mq_cancel_work_sync(disk->queue);
+ if (queue_is_mq(disk->queue))
+ disk_release_mq(disk->queue);
blkcg_exit_queue(disk->queue);