Skip to content

Commit 28ce942

Browse files
Ming Leiaxboe
authored andcommitted
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>
1 parent ba3e845 commit 28ce942

2 files changed

Lines changed: 30 additions & 17 deletions

File tree

block/blk-sysfs.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -739,20 +739,6 @@ static void blk_free_queue_rcu(struct rcu_head *rcu_head)
739739
kmem_cache_free(blk_get_queue_kmem_cache(blk_queue_has_srcu(q)), q);
740740
}
741741

742-
/* Unconfigure the I/O scheduler and dissociate from the cgroup controller. */
743-
static void blk_exit_queue(struct request_queue *q)
744-
{
745-
/*
746-
* Since the I/O scheduler exit code may access cgroup information,
747-
* perform I/O scheduler exit before disassociating from the block
748-
* cgroup controller.
749-
*/
750-
if (q->elevator) {
751-
ioc_clear_queue(q);
752-
elevator_exit(q);
753-
}
754-
}
755-
756742
/**
757743
* blk_release_queue - releases all allocated resources of the request_queue
758744
* @kobj: pointer to a kobject, whose container is a request_queue
@@ -786,8 +772,6 @@ static void blk_release_queue(struct kobject *kobj)
786772
blk_stat_remove_callback(q, q->poll_cb);
787773
blk_stat_free_callback(q->poll_cb);
788774

789-
blk_exit_queue(q);
790-
791775
blk_free_queue_stats(q->stats);
792776
kfree(q->poll_stat);
793777

block/genhd.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,34 @@ static const struct attribute_group *disk_attr_groups[] = {
10981098
NULL
10991099
};
11001100

1101+
static void disk_release_mq(struct request_queue *q)
1102+
{
1103+
blk_mq_cancel_work_sync(q);
1104+
1105+
/*
1106+
* There can't be any non non-passthrough bios in flight here, but
1107+
* requests stay around longer, including passthrough ones so we
1108+
* still need to freeze the queue here.
1109+
*/
1110+
blk_mq_freeze_queue(q);
1111+
1112+
/*
1113+
* Since the I/O scheduler exit code may access cgroup information,
1114+
* perform I/O scheduler exit before disassociating from the block
1115+
* cgroup controller.
1116+
*/
1117+
if (q->elevator) {
1118+
ioc_clear_queue(q);
1119+
1120+
mutex_lock(&q->sysfs_lock);
1121+
blk_mq_sched_free_rqs(q);
1122+
elevator_exit(q);
1123+
mutex_unlock(&q->sysfs_lock);
1124+
}
1125+
1126+
__blk_mq_unfreeze_queue(q, true);
1127+
}
1128+
11011129
/**
11021130
* disk_release - releases all allocated resources of the gendisk
11031131
* @dev: the device representing this disk
@@ -1119,7 +1147,8 @@ static void disk_release(struct device *dev)
11191147
might_sleep();
11201148
WARN_ON_ONCE(disk_live(disk));
11211149

1122-
blk_mq_cancel_work_sync(disk->queue);
1150+
if (queue_is_mq(disk->queue))
1151+
disk_release_mq(disk->queue);
11231152

11241153
blkcg_exit_queue(disk->queue);
11251154

0 commit comments

Comments
 (0)