diff --git a/block/elevator.c b/block/elevator.c index 293c5c81397a19e54528b3751d0044ab816fe368..dc756d4c2678a2e028b325af79bb166ddd016b6c 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -662,6 +662,7 @@ void elevator_init_mq(struct request_queue *q) { struct elevator_type *e; int err; + bool no_init_io; if (!elv_support_iosched(q)) return; @@ -678,13 +679,18 @@ void elevator_init_mq(struct request_queue *q) if (!e) return; - blk_mq_freeze_queue(q); - blk_mq_quiesce_queue(q); + no_init_io = blk_queue_no_init_io(q); + if (!no_init_io) { + blk_mq_freeze_queue(q); + blk_mq_quiesce_queue(q); + } err = blk_mq_init_sched(q, e); - blk_mq_unquiesce_queue(q); - blk_mq_unfreeze_queue(q); + if (!no_init_io) { + blk_mq_unquiesce_queue(q); + blk_mq_unfreeze_queue(q); + } if (err) { pr_warn("\"%s\" elevator initialization failed, " diff --git a/drivers/block/loop.c b/drivers/block/loop.c index cd13c0eb3f634e1817104aff1fd3f4e6cf03bb51..31b1ef73b98159c9146879a572bca3833fef2fac 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -2175,6 +2175,11 @@ static int loop_add(struct loop_device **l, int i) disk->private_data = lo; disk->queue = lo->lo_queue; sprintf(disk->disk_name, "loop%d", i); + /* + * There won't be io before add_disk, QUEUE_FLAG_NO_INIT_IO can help + * to save time while elevator_init_mq. + */ + blk_queue_flag_set(QUEUE_FLAG_NO_INIT_IO, lo->lo_queue); add_disk(disk); *l = lo; return lo->lo_number; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 542471b76f4106ed64430f4dd2c13fd8f9aedbc0..00e71019f4f681adc930e23fd08b3ee4fd9e051f 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -621,6 +621,7 @@ struct request_queue { #define QUEUE_FLAG_RQ_ALLOC_TIME 27 /* record rq->alloc_time_ns */ #define QUEUE_FLAG_HCTX_ACTIVE 28 /* at least one blk-mq hctx is active */ #define QUEUE_FLAG_NOWAIT 29 /* device supports NOWAIT */ +#define QUEUE_FLAG_NO_INIT_IO 30 /* no IO can happen while elevator_init_mq */ #define QUEUE_FLAG_MQ_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_SAME_COMP) | \ @@ -667,6 +668,7 @@ bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q); #define blk_queue_fua(q) test_bit(QUEUE_FLAG_FUA, &(q)->queue_flags) #define blk_queue_registered(q) test_bit(QUEUE_FLAG_REGISTERED, &(q)->queue_flags) #define blk_queue_nowait(q) test_bit(QUEUE_FLAG_NOWAIT, &(q)->queue_flags) +#define blk_queue_no_init_io(q) test_bit(QUEUE_FLAG_NO_INIT_IO, &(q)->queue_flags) extern void blk_set_pm_only(struct request_queue *q); extern void blk_clear_pm_only(struct request_queue *q);