From 5dc0acc2c46d9d5e91d9b4a5ffb9711617846886 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Thu, 25 Jul 2019 17:41:46 +0800 Subject: [PATCH 1005/2944] blk-mq: balance mapping between present CPUs and queues fix #27417914 commit 556f36e90dbe7dded81f4fac084d2bc8a2458330 upstream Spread queues among present CPUs first, then building mapping on other non-present CPUs. So we can minimize count of dead queues which are mapped by un-present CPUs only. Then bad IO performance can be avoided by unbalanced mapping between present CPUs and queues. The similar policy has been applied on Managed IRQ affinity. Cc: Yi Zhang Reported-by: Yi Zhang Reviewed-by: Bob Liu Signed-off-by: Ming Lei Signed-off-by: Jens Axboe [jeffle: remove code supporting multiple queue maps, which is merged since v5.0] Signed-off-by: Jeffle Xu Reviewed-by: Joseph Qi --- block/blk-mq-cpumap.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/block/blk-mq-cpumap.c b/block/blk-mq-cpumap.c index 3eb169f..7581901 100644 --- a/block/blk-mq-cpumap.c +++ b/block/blk-mq-cpumap.c @@ -14,9 +14,9 @@ #include "blk.h" #include "blk-mq.h" -static int cpu_to_queue_index(unsigned int nr_queues, const int cpu) +static int queue_index(unsigned int nr_queues, const int q) { - return cpu % nr_queues; + return q % nr_queues; } static int get_first_sibling(unsigned int cpu) @@ -34,9 +34,24 @@ int blk_mq_map_queues(struct blk_mq_tag_set *set) { unsigned int *map = set->mq_map; unsigned int nr_queues = set->nr_hw_queues; - unsigned int cpu, first_sibling; + unsigned int cpu, first_sibling, q = 0; + + for_each_possible_cpu(cpu) + map[cpu] = -1; + + /* + * Spread queues among present CPUs first for minimizing + * count of dead queues which are mapped by all un-present CPUs + */ + for_each_present_cpu(cpu) { + if (q >= nr_queues) + break; + map[cpu] = queue_index(nr_queues, q++); + } for_each_possible_cpu(cpu) { + if (map[cpu] != -1) + continue; /* * First do sequential mapping between CPUs and queues. * In case we still have CPUs to map, and we have some number of @@ -44,11 +59,11 @@ int blk_mq_map_queues(struct blk_mq_tag_set *set) * performace optimizations. */ if (cpu < nr_queues) { - map[cpu] = cpu_to_queue_index(nr_queues, cpu); + map[cpu] = queue_index(nr_queues, q++); } else { first_sibling = get_first_sibling(cpu); if (first_sibling == cpu) - map[cpu] = cpu_to_queue_index(nr_queues, cpu); + map[cpu] = queue_index(nr_queues, q++); else map[cpu] = map[first_sibling]; } -- 1.8.3.1