Skip to content

Commit 20e4d81

Browse files
Christoph Hellwigaxboe
authored andcommitted
blk-mq: simplify queue mapping & schedule with each possisble CPU
The previous patch assigns interrupt vectors to all possible CPUs, so now hctx can be mapped to possible CPUs, this patch applies this fact to simplify queue mapping & schedule so that we don't need to handle CPU hotplug for dealing with physical CPU plug & unplug. With this simplication, we can work well on physical CPU plug & unplug, which is a normal use case for VM at least. Make sure we allocate blk_mq_ctx structures for all possible CPUs, and set hctx->numa_node for possible CPUs which are mapped to this hctx. And only choose the online CPUs for schedule. Reported-by: Christian Borntraeger <[email protected]> Tested-by: Christian Borntraeger <[email protected]> Tested-by: Stefan Haberland <[email protected]> Cc: Thomas Gleixner <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> Fixes: 4b855ad ("blk-mq: Create hctx for each present CPU") (merged the three into one because any single one may not work, and fix selecting online CPUs for scheduler) Signed-off-by: Ming Lei <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 84676c1 commit 20e4d81

File tree

1 file changed

+8
-11
lines changed

1 file changed

+8
-11
lines changed

block/blk-mq.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
440440
blk_queue_exit(q);
441441
return ERR_PTR(-EXDEV);
442442
}
443-
cpu = cpumask_first(alloc_data.hctx->cpumask);
443+
cpu = cpumask_first_and(alloc_data.hctx->cpumask, cpu_online_mask);
444444
alloc_data.ctx = __blk_mq_get_ctx(q, cpu);
445445

446446
rq = blk_mq_get_request(q, NULL, op, &alloc_data);
@@ -1324,9 +1324,10 @@ static int blk_mq_hctx_next_cpu(struct blk_mq_hw_ctx *hctx)
13241324
if (--hctx->next_cpu_batch <= 0) {
13251325
int next_cpu;
13261326

1327-
next_cpu = cpumask_next(hctx->next_cpu, hctx->cpumask);
1327+
next_cpu = cpumask_next_and(hctx->next_cpu, hctx->cpumask,
1328+
cpu_online_mask);
13281329
if (next_cpu >= nr_cpu_ids)
1329-
next_cpu = cpumask_first(hctx->cpumask);
1330+
next_cpu = cpumask_first_and(hctx->cpumask,cpu_online_mask);
13301331

13311332
hctx->next_cpu = next_cpu;
13321333
hctx->next_cpu_batch = BLK_MQ_CPU_WORK_BATCH;
@@ -2220,16 +2221,11 @@ static void blk_mq_init_cpu_queues(struct request_queue *q,
22202221
INIT_LIST_HEAD(&__ctx->rq_list);
22212222
__ctx->queue = q;
22222223

2223-
/* If the cpu isn't present, the cpu is mapped to first hctx */
2224-
if (!cpu_present(i))
2225-
continue;
2226-
2227-
hctx = blk_mq_map_queue(q, i);
2228-
22292224
/*
22302225
* Set local node, IFF we have more than one hw queue. If
22312226
* not, we remain on the home node of the device
22322227
*/
2228+
hctx = blk_mq_map_queue(q, i);
22332229
if (nr_hw_queues > 1 && hctx->numa_node == NUMA_NO_NODE)
22342230
hctx->numa_node = local_memory_node(cpu_to_node(i));
22352231
}
@@ -2286,7 +2282,7 @@ static void blk_mq_map_swqueue(struct request_queue *q)
22862282
*
22872283
* If the cpu isn't present, the cpu is mapped to first hctx.
22882284
*/
2289-
for_each_present_cpu(i) {
2285+
for_each_possible_cpu(i) {
22902286
hctx_idx = q->mq_map[i];
22912287
/* unmapped hw queue can be remapped after CPU topo changed */
22922288
if (!set->tags[hctx_idx] &&
@@ -2340,7 +2336,8 @@ static void blk_mq_map_swqueue(struct request_queue *q)
23402336
/*
23412337
* Initialize batch roundrobin counts
23422338
*/
2343-
hctx->next_cpu = cpumask_first(hctx->cpumask);
2339+
hctx->next_cpu = cpumask_first_and(hctx->cpumask,
2340+
cpu_online_mask);
23442341
hctx->next_cpu_batch = BLK_MQ_CPU_WORK_BATCH;
23452342
}
23462343
}

0 commit comments

Comments
 (0)