diff mbox series

block: drain queue after disk is removed from sysfs

Message ID 20211026101204.2897166-1-ming.lei@redhat.com (mailing list archive)
State New, archived
Headers show
Series block: drain queue after disk is removed from sysfs | expand

Commit Message

Ming Lei Oct. 26, 2021, 10:12 a.m. UTC
Before removing disk from sysfs, userspace still may change queue via
sysfs, such as switching elevator or setting wbt latency, both may
reinitialize wbt, then the warning in blk_free_queue_stats() will be
triggered since rq_qos_exit() is moved to del_gendisk().

Fixes the issue by moving draining queue & tearing down after disk is
removed from sysfs, at that time no one can come into queue's
store()/show().

Reported-by: Yi Zhang <yi.zhang@redhat.com>
Tested-by: Yi Zhang <yi.zhang@redhat.com>
Fixes: 8e141f9eb803 ("block: drain file system I/O on del_gendisk")
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 block/genhd.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

Comments

Jens Axboe Oct. 26, 2021, 2:44 p.m. UTC | #1
On Tue, 26 Oct 2021 18:12:04 +0800, Ming Lei wrote:
> Before removing disk from sysfs, userspace still may change queue via
> sysfs, such as switching elevator or setting wbt latency, both may
> reinitialize wbt, then the warning in blk_free_queue_stats() will be
> triggered since rq_qos_exit() is moved to del_gendisk().
> 
> Fixes the issue by moving draining queue & tearing down after disk is
> removed from sysfs, at that time no one can come into queue's
> store()/show().
> 
> [...]

Applied, thanks!

[1/1] block: drain queue after disk is removed from sysfs
      commit: d308ae0d299a6bb15be4efb91849582d19c23213

Best regards,
diff mbox series

Patch

diff --git a/block/genhd.c b/block/genhd.c
index 64f83c4aee99..2052aeffa39b 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -589,16 +589,6 @@  void del_gendisk(struct gendisk *disk)
 	 * Prevent new I/O from crossing bio_queue_enter().
 	 */
 	blk_queue_start_drain(q);
-	blk_mq_freeze_queue_wait(q);
-
-	rq_qos_exit(q);
-	blk_sync_queue(q);
-	blk_flush_integrity();
-	/*
-	 * Allow using passthrough request again after the queue is torn down.
-	 */
-	blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q);
-	__blk_mq_unfreeze_queue(q, true);
 
 	if (!(disk->flags & GENHD_FL_HIDDEN)) {
 		sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
@@ -621,6 +611,18 @@  void del_gendisk(struct gendisk *disk)
 		sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
 	pm_runtime_set_memalloc_noio(disk_to_dev(disk), false);
 	device_del(disk_to_dev(disk));
+
+	blk_mq_freeze_queue_wait(q);
+
+	rq_qos_exit(q);
+	blk_sync_queue(q);
+	blk_flush_integrity();
+	/*
+	 * Allow using passthrough request again after the queue is torn down.
+	 */
+	blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q);
+	__blk_mq_unfreeze_queue(q, true);
+
 }
 EXPORT_SYMBOL(del_gendisk);