Skip to content

Commit 50e34d7

Browse files
Christoph Hellwigaxboe
authored andcommitted
block: disable the elevator int del_gendisk
The elevator is only used for file system requests, which are stopped in del_gendisk. Move disabling the elevator and freeing the scheduler tags to the end of del_gendisk instead of doing that work in disk_release and blk_cleanup_queue to avoid a use after free on q->tag_set from disk_release as the tag_set might not be alive at that point. Move the blk_qos_exit call as well, as it just depends on the elevator exit and would be the only reason to keep the not exactly cheap queue freeze in disk_release. Fixes: e155b0c ("blk-mq: Use shared tags for shared sbitmap support") Reported-by: [email protected] Signed-off-by: Christoph Hellwig <[email protected]> Tested-by: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent b96f3ca commit 50e34d7

File tree

2 files changed

+11
-41
lines changed

2 files changed

+11
-41
lines changed

block/blk-core.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -322,19 +322,6 @@ void blk_cleanup_queue(struct request_queue *q)
322322
blk_mq_exit_queue(q);
323323
}
324324

325-
/*
326-
* In theory, request pool of sched_tags belongs to request queue.
327-
* However, the current implementation requires tag_set for freeing
328-
* requests, so free the pool now.
329-
*
330-
* Queue has become frozen, there can't be any in-queue requests, so
331-
* it is safe to free requests now.
332-
*/
333-
mutex_lock(&q->sysfs_lock);
334-
if (q->elevator)
335-
blk_mq_sched_free_rqs(q);
336-
mutex_unlock(&q->sysfs_lock);
337-
338325
/* @q is and will stay empty, shutdown and put */
339326
blk_put_queue(q);
340327
}

block/genhd.c

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,17 @@ void del_gendisk(struct gendisk *disk)
652652

653653
blk_sync_queue(q);
654654
blk_flush_integrity();
655+
blk_mq_cancel_work_sync(q);
656+
657+
blk_mq_quiesce_queue(q);
658+
if (q->elevator) {
659+
mutex_lock(&q->sysfs_lock);
660+
elevator_exit(q);
661+
mutex_unlock(&q->sysfs_lock);
662+
}
663+
rq_qos_exit(q);
664+
blk_mq_unquiesce_queue(q);
665+
655666
/*
656667
* Allow using passthrough request again after the queue is torn down.
657668
*/
@@ -1120,31 +1131,6 @@ static const struct attribute_group *disk_attr_groups[] = {
11201131
NULL
11211132
};
11221133

1123-
static void disk_release_mq(struct request_queue *q)
1124-
{
1125-
blk_mq_cancel_work_sync(q);
1126-
1127-
/*
1128-
* There can't be any non non-passthrough bios in flight here, but
1129-
* requests stay around longer, including passthrough ones so we
1130-
* still need to freeze the queue here.
1131-
*/
1132-
blk_mq_freeze_queue(q);
1133-
1134-
/*
1135-
* Since the I/O scheduler exit code may access cgroup information,
1136-
* perform I/O scheduler exit before disassociating from the block
1137-
* cgroup controller.
1138-
*/
1139-
if (q->elevator) {
1140-
mutex_lock(&q->sysfs_lock);
1141-
elevator_exit(q);
1142-
mutex_unlock(&q->sysfs_lock);
1143-
}
1144-
rq_qos_exit(q);
1145-
__blk_mq_unfreeze_queue(q, true);
1146-
}
1147-
11481134
/**
11491135
* disk_release - releases all allocated resources of the gendisk
11501136
* @dev: the device representing this disk
@@ -1166,9 +1152,6 @@ static void disk_release(struct device *dev)
11661152
might_sleep();
11671153
WARN_ON_ONCE(disk_live(disk));
11681154

1169-
if (queue_is_mq(disk->queue))
1170-
disk_release_mq(disk->queue);
1171-
11721155
blkcg_exit_queue(disk->queue);
11731156

11741157
disk_release_events(disk);

0 commit comments

Comments
 (0)