Skip to content

Commit

Permalink
block: move blk_exit_queue into disk_release
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ming Lei authored and Jens Axboe committed Mar 9, 2022
1 parent ba3e845 commit 28ce942
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 17 deletions.
16 changes: 0 additions & 16 deletions block/blk-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,20 +739,6 @@ static void blk_free_queue_rcu(struct rcu_head *rcu_head)
kmem_cache_free(blk_get_queue_kmem_cache(blk_queue_has_srcu(q)), q);
}

/* Unconfigure the I/O scheduler and dissociate from the cgroup controller. */
static void blk_exit_queue(struct request_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);
elevator_exit(q);
}
}

/**
* blk_release_queue - releases all allocated resources of the request_queue
* @kobj: pointer to a kobject, whose container is a request_queue
Expand Down Expand Up @@ -786,8 +772,6 @@ static void blk_release_queue(struct kobject *kobj)
blk_stat_remove_callback(q, q->poll_cb);
blk_stat_free_callback(q->poll_cb);

blk_exit_queue(q);

blk_free_queue_stats(q->stats);
kfree(q->poll_stat);

Expand Down
31 changes: 30 additions & 1 deletion block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);

Expand Down

0 comments on commit 28ce942

Please sign in to comment.