If the default elevator chosen is mq-deadline, elevator_init_mq() may return an error if the mq-deadline initialization fails, leading to blk_mq_init_allocated_queue() returning an error, which in turn will cause the block device initialization to fail.
Instead of taking such extreme measure, handle mq-deadline initialization failures in the same manner as if mq-deadline being not available (no module to load), that is, default to the "none" scheduler. With this change, elevator_init_mq() return type can be changed to void. Signed-off-by: Damien Le Moal <damien.lem...@wdc.com> --- block/blk-mq.c | 8 +------- block/blk.h | 2 +- block/elevator.c | 17 ++++++++++------- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 556c774a0f0d..274e168c8535 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2846,8 +2846,6 @@ static unsigned int nr_hw_queues(struct blk_mq_tag_set *set) struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, struct request_queue *q) { - int ret = -ENOMEM; - /* mark the queue as mq asap */ q->mq_ops = set->ops; @@ -2908,14 +2906,10 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, blk_mq_add_queue_tag_set(set, q); blk_mq_map_swqueue(q); - ret = elevator_init_mq(q); - if (ret) - goto err_tag_set; + elevator_init_mq(q); return q; -err_tag_set: - blk_mq_del_queue_tag_set(q); err_hctxs: kfree(q->queue_hw_ctx); q->nr_hw_queues = 0; diff --git a/block/blk.h b/block/blk.h index de6b2e146d6e..ddb292bb6caf 100644 --- a/block/blk.h +++ b/block/blk.h @@ -184,7 +184,7 @@ void blk_account_io_done(struct request *req, u64 now); void blk_insert_flush(struct request *rq); -int elevator_init_mq(struct request_queue *q); +void elevator_init_mq(struct request_queue *q); int elevator_switch_mq(struct request_queue *q, struct elevator_type *new_e); void __elevator_exit(struct request_queue *, struct elevator_queue *); diff --git a/block/elevator.c b/block/elevator.c index 1ed2710f1950..7fff06751633 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -603,19 +603,19 @@ static inline bool elv_support_iosched(struct request_queue *q) /* * For blk-mq devices supporting IO scheduling, we default to using mq-deadline, - * if available, for single queue devices. If deadline isn't available OR we - * have multiple queues, default to "none". + * if available, for single queue devices. If deadline isn't available OR + * deadline initialization fails OR we have multiple queues, default to "none". */ -int elevator_init_mq(struct request_queue *q) +void elevator_init_mq(struct request_queue *q) { struct elevator_type *e; int err = 0; if (!elv_support_iosched(q)) - return 0; + return; if (q->nr_hw_queues != 1) - return 0; + return; /* * q->sysfs_lock must be held to provide mutual exclusion between @@ -630,11 +630,14 @@ int elevator_init_mq(struct request_queue *q) goto out_unlock; err = blk_mq_init_sched(q, e); - if (err) + if (err) { + pr_warn("\"%s\" elevator initialization failed, " + "falling back to \"none\"\n", e->elevator_name); elevator_put(e); + } + out_unlock: mutex_unlock(&q->sysfs_lock); - return err; } -- 2.21.0