summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMing Lei <ming.lei@redhat.com>2019-05-14 23:03:08 -0400
committerJens Axboe <axboe@kernel.dk>2019-05-29 08:09:09 -0400
commit47cdee29ef9d94e485eb08f962c74943023a5271 (patch)
tree2bce0a16a4235e5a9b4635a3db4b2dabceb532ce
parent31cb1d64da4ebd214348cad9d86e663c831c45fc (diff)
block: move blk_exit_queue into __blk_release_queue
Commit 498f6650aec8 ("block: Fix a race between the cgroup code and request queue initialization") moves what blk_exit_queue does into blk_cleanup_queue() for fixing issue caused by changing back queue lock. However, after legacy request IO path is killed, driver queue lock won't be used at all, and there isn't story for changing back queue lock. Then the issue addressed by Commit 498f6650aec8 doesn't exist any more. So move move blk_exit_queue into __blk_release_queue. This patch basically reverts the following two commits: 498f6650aec8 block: Fix a race between the cgroup code and request queue initialization 24ecc3585348 block: Ensure that a request queue is dissociated from the cgroup controller Cc: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--block/blk-core.c37
-rw-r--r--block/blk-sysfs.c47
-rw-r--r--block/blk.h1
3 files changed, 32 insertions, 53 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index 1bf83a0df0f6..25faab079abf 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -282,35 +282,6 @@ void blk_set_queue_dying(struct request_queue *q)
282} 282}
283EXPORT_SYMBOL_GPL(blk_set_queue_dying); 283EXPORT_SYMBOL_GPL(blk_set_queue_dying);
284 284
285/* Unconfigure the I/O scheduler and dissociate from the cgroup controller. */
286void blk_exit_queue(struct request_queue *q)
287{
288 /*
289 * Since the I/O scheduler exit code may access cgroup information,
290 * perform I/O scheduler exit before disassociating from the block
291 * cgroup controller.
292 */
293 if (q->elevator) {
294 ioc_clear_queue(q);
295 elevator_exit(q, q->elevator);
296 q->elevator = NULL;
297 }
298
299 /*
300 * Remove all references to @q from the block cgroup controller before
301 * restoring @q->queue_lock to avoid that restoring this pointer causes
302 * e.g. blkcg_print_blkgs() to crash.
303 */
304 blkcg_exit_queue(q);
305
306 /*
307 * Since the cgroup code may dereference the @q->backing_dev_info
308 * pointer, only decrease its reference count after having removed the
309 * association with the block cgroup controller.
310 */
311 bdi_put(q->backing_dev_info);
312}
313
314/** 285/**
315 * blk_cleanup_queue - shutdown a request queue 286 * blk_cleanup_queue - shutdown a request queue
316 * @q: request queue to shutdown 287 * @q: request queue to shutdown
@@ -346,14 +317,6 @@ void blk_cleanup_queue(struct request_queue *q)
346 del_timer_sync(&q->backing_dev_info->laptop_mode_wb_timer); 317 del_timer_sync(&q->backing_dev_info->laptop_mode_wb_timer);
347 blk_sync_queue(q); 318 blk_sync_queue(q);
348 319
349 /*
350 * I/O scheduler exit is only safe after the sysfs scheduler attribute
351 * has been removed.
352 */
353 WARN_ON_ONCE(q->kobj.state_in_sysfs);
354
355 blk_exit_queue(q);
356
357 if (queue_is_mq(q)) 320 if (queue_is_mq(q))
358 blk_mq_exit_queue(q); 321 blk_mq_exit_queue(q);
359 322
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index a16a02c52a85..75b5281cc577 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -840,6 +840,36 @@ static void blk_free_queue_rcu(struct rcu_head *rcu_head)
840 kmem_cache_free(blk_requestq_cachep, q); 840 kmem_cache_free(blk_requestq_cachep, q);
841} 841}
842 842
843/* Unconfigure the I/O scheduler and dissociate from the cgroup controller. */
844static void blk_exit_queue(struct request_queue *q)
845{
846 /*
847 * Since the I/O scheduler exit code may access cgroup information,
848 * perform I/O scheduler exit before disassociating from the block
849 * cgroup controller.
850 */
851 if (q->elevator) {
852 ioc_clear_queue(q);
853 elevator_exit(q, q->elevator);
854 q->elevator = NULL;
855 }
856
857 /*
858 * Remove all references to @q from the block cgroup controller before
859 * restoring @q->queue_lock to avoid that restoring this pointer causes
860 * e.g. blkcg_print_blkgs() to crash.
861 */
862 blkcg_exit_queue(q);
863
864 /*
865 * Since the cgroup code may dereference the @q->backing_dev_info
866 * pointer, only decrease its reference count after having removed the
867 * association with the block cgroup controller.
868 */
869 bdi_put(q->backing_dev_info);
870}
871
872
843/** 873/**
844 * __blk_release_queue - release a request queue 874 * __blk_release_queue - release a request queue
845 * @work: pointer to the release_work member of the request queue to be released 875 * @work: pointer to the release_work member of the request queue to be released
@@ -860,23 +890,10 @@ static void __blk_release_queue(struct work_struct *work)
860 blk_stat_remove_callback(q, q->poll_cb); 890 blk_stat_remove_callback(q, q->poll_cb);
861 blk_stat_free_callback(q->poll_cb); 891 blk_stat_free_callback(q->poll_cb);
862 892
863 if (!blk_queue_dead(q)) {
864 /*
865 * Last reference was dropped without having called
866 * blk_cleanup_queue().
867 */
868 WARN_ONCE(blk_queue_init_done(q),
869 "request queue %p has been registered but blk_cleanup_queue() has not been called for that queue\n",
870 q);
871 blk_exit_queue(q);
872 }
873
874 WARN(blk_queue_root_blkg(q),
875 "request queue %p is being released but it has not yet been removed from the blkcg controller\n",
876 q);
877
878 blk_free_queue_stats(q->stats); 893 blk_free_queue_stats(q->stats);
879 894
895 blk_exit_queue(q);
896
880 blk_queue_free_zone_bitmaps(q); 897 blk_queue_free_zone_bitmaps(q);
881 898
882 if (queue_is_mq(q)) 899 if (queue_is_mq(q))
diff --git a/block/blk.h b/block/blk.h
index e27fd1512e4b..91b3581b7c7a 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -50,7 +50,6 @@ struct blk_flush_queue *blk_alloc_flush_queue(struct request_queue *q,
50 int node, int cmd_size, gfp_t flags); 50 int node, int cmd_size, gfp_t flags);
51void blk_free_flush_queue(struct blk_flush_queue *q); 51void blk_free_flush_queue(struct blk_flush_queue *q);
52 52
53void blk_exit_queue(struct request_queue *q);
54void blk_rq_bio_prep(struct request_queue *q, struct request *rq, 53void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
55 struct bio *bio); 54 struct bio *bio);
56void blk_freeze_queue(struct request_queue *q); 55void blk_freeze_queue(struct request_queue *q);