diff options
| author | Omar Sandoval <osandov@fb.com> | 2017-04-07 10:53:11 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@fb.com> | 2017-04-07 10:56:49 -0400 |
| commit | ebe8bddb6e30d7a02775b9972099271fc5910f37 (patch) | |
| tree | bf15660fb38869b2e4edc574a20b4415c9cd5cf6 | |
| parent | 54d5329d425650fafaf90660a139c771d2d49cae (diff) | |
blk-mq: remap queues when adding/removing hardware queues
blk_mq_update_nr_hw_queues() used to remap hardware queues, which is the
behavior that drivers expect. However, commit 4e68a011428a changed
blk_mq_queue_reinit() to not remap queues for the case of CPU
hotplugging, inadvertently making blk_mq_update_nr_hw_queues() not remap
queues as well. This breaks, for example, NBD's multi-connection mode,
leaving the added hardware queues unused. Fix it by making
blk_mq_update_nr_hw_queues() explicitly remap the queues.
Fixes: 4e68a011428a ("blk-mq: don't redistribute hardware queues on a CPU hotplug event")
Reviewed-by: Keith Busch <keith.busch@intel.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
| -rw-r--r-- | block/blk-mq.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index cfb7c97b14ec..f1be5c3eb600 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -2570,6 +2570,14 @@ static int blk_mq_alloc_rq_maps(struct blk_mq_tag_set *set) | |||
| 2570 | return 0; | 2570 | return 0; |
| 2571 | } | 2571 | } |
| 2572 | 2572 | ||
| 2573 | static int blk_mq_update_queue_map(struct blk_mq_tag_set *set) | ||
| 2574 | { | ||
| 2575 | if (set->ops->map_queues) | ||
| 2576 | return set->ops->map_queues(set); | ||
| 2577 | else | ||
| 2578 | return blk_mq_map_queues(set); | ||
| 2579 | } | ||
| 2580 | |||
| 2573 | /* | 2581 | /* |
| 2574 | * Alloc a tag set to be associated with one or more request queues. | 2582 | * Alloc a tag set to be associated with one or more request queues. |
| 2575 | * May fail with EINVAL for various error conditions. May adjust the | 2583 | * May fail with EINVAL for various error conditions. May adjust the |
| @@ -2624,10 +2632,7 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set) | |||
| 2624 | if (!set->mq_map) | 2632 | if (!set->mq_map) |
| 2625 | goto out_free_tags; | 2633 | goto out_free_tags; |
| 2626 | 2634 | ||
| 2627 | if (set->ops->map_queues) | 2635 | ret = blk_mq_update_queue_map(set); |
| 2628 | ret = set->ops->map_queues(set); | ||
| 2629 | else | ||
| 2630 | ret = blk_mq_map_queues(set); | ||
| 2631 | if (ret) | 2636 | if (ret) |
| 2632 | goto out_free_mq_map; | 2637 | goto out_free_mq_map; |
| 2633 | 2638 | ||
| @@ -2719,6 +2724,7 @@ void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues) | |||
| 2719 | blk_mq_freeze_queue(q); | 2724 | blk_mq_freeze_queue(q); |
| 2720 | 2725 | ||
| 2721 | set->nr_hw_queues = nr_hw_queues; | 2726 | set->nr_hw_queues = nr_hw_queues; |
| 2727 | blk_mq_update_queue_map(set); | ||
| 2722 | list_for_each_entry(q, &set->tag_list, tag_set_list) { | 2728 | list_for_each_entry(q, &set->tag_list, tag_set_list) { |
| 2723 | blk_mq_realloc_hw_ctxs(set, q); | 2729 | blk_mq_realloc_hw_ctxs(set, q); |
| 2724 | 2730 | ||
