diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-mq.c | 8 | ||||
-rw-r--r-- | block/blk-rq-qos.c | 2 | ||||
-rw-r--r-- | block/elevator.c | 21 |
3 files changed, 21 insertions, 10 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 4b2c8e940f59..cf626e061dd7 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -4310,6 +4310,12 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, /* mark the queue as mq asap */ q->mq_ops = set->ops; + /* + * ->tag_set has to be setup before initialize hctx, which cpuphp + * handler needs it for checking queue mapping + */ + q->tag_set = set; + if (blk_mq_alloc_ctxs(q)) goto err_exit; @@ -4328,8 +4334,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, INIT_WORK(&q->timeout_work, blk_mq_timeout_work); blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ); - q->tag_set = set; - q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; INIT_DELAYED_WORK(&q->requeue_work, blk_mq_requeue_work); diff --git a/block/blk-rq-qos.c b/block/blk-rq-qos.c index 2cfb297d9a62..058f92c4f9d5 100644 --- a/block/blk-rq-qos.c +++ b/block/blk-rq-qos.c @@ -219,8 +219,8 @@ static int rq_qos_wake_function(struct wait_queue_entry *curr, data->got_token = true; smp_wmb(); - list_del_init(&curr->entry); wake_up_process(data->task); + list_del_init_careful(&curr->entry); return 1; } diff --git a/block/elevator.c b/block/elevator.c index 4122026b11f1..9430cde13d1a 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -106,8 +106,7 @@ static struct elevator_type *__elevator_find(const char *name) return NULL; } -static struct elevator_type *elevator_find_get(struct request_queue *q, - const char *name) +static struct elevator_type *elevator_find_get(const char *name) { struct elevator_type *e; @@ -551,7 +550,7 @@ EXPORT_SYMBOL_GPL(elv_unregister); static inline bool elv_support_iosched(struct request_queue *q) { if (!queue_is_mq(q) || - (q->tag_set && (q->tag_set->flags & BLK_MQ_F_NO_SCHED))) + (q->tag_set->flags & BLK_MQ_F_NO_SCHED)) return false; return true; } @@ -562,14 +561,14 @@ static inline bool elv_support_iosched(struct request_queue *q) */ static struct elevator_type *elevator_get_default(struct request_queue *q) { - if (q->tag_set && q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT) + if (q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT) return NULL; if (q->nr_hw_queues != 1 && !blk_mq_is_shared_tags(q->tag_set->flags)) return NULL; - return elevator_find_get(q, "mq-deadline"); + return elevator_find_get("mq-deadline"); } /* @@ -697,7 +696,7 @@ static int elevator_change(struct request_queue *q, const char *elevator_name) if (q->elevator && elevator_match(q->elevator->type, elevator_name)) return 0; - e = elevator_find_get(q, elevator_name); + e = elevator_find_get(elevator_name); if (!e) return -EINVAL; ret = elevator_switch(q, e); @@ -709,13 +708,21 @@ int elv_iosched_load_module(struct gendisk *disk, const char *buf, size_t count) { char elevator_name[ELV_NAME_MAX]; + struct elevator_type *found; + const char *name; if (!elv_support_iosched(disk->queue)) return -EOPNOTSUPP; strscpy(elevator_name, buf, sizeof(elevator_name)); + name = strstrip(elevator_name); - request_module("%s-iosched", strstrip(elevator_name)); + spin_lock(&elv_list_lock); + found = __elevator_find(name); + spin_unlock(&elv_list_lock); + + if (!found) + request_module("%s-iosched", name); return 0; } |