Skip to content

Commit 4b855ad

Browse files
Christoph HellwigKAGA-KOKO
authored andcommitted
blk-mq: Create hctx for each present CPU
Currently we only create hctx for online CPUs, which can lead to a lot of churn due to frequent soft offline / online operations. Instead allocate one for each present CPU to avoid this and dramatically simplify the code. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jens Axboe <axboe@kernel.dk> Cc: Keith Busch <keith.busch@intel.com> Cc: linux-block@vger.kernel.org Cc: linux-nvme@lists.infradead.org Link: http://lkml.kernel.org/r/20170626102058.10200-3-hch@lst.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
1 parent 5f042e7 commit 4b855ad

File tree

3 files changed

+11
-115
lines changed

3 files changed

+11
-115
lines changed

block/blk-mq.c

Lines changed: 11 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@
3737
#include "blk-wbt.h"
3838
#include "blk-mq-sched.h"
3939

40-
static DEFINE_MUTEX(all_q_mutex);
41-
static LIST_HEAD(all_q_list);
42-
4340
static void blk_mq_poll_stats_start(struct request_queue *q);
4441
static void blk_mq_poll_stats_fn(struct blk_stat_callback *cb);
4542
static void __blk_mq_stop_hw_queues(struct request_queue *q, bool sync);
@@ -1975,8 +1972,8 @@ static void blk_mq_init_cpu_queues(struct request_queue *q,
19751972
INIT_LIST_HEAD(&__ctx->rq_list);
19761973
__ctx->queue = q;
19771974

1978-
/* If the cpu isn't online, the cpu is mapped to first hctx */
1979-
if (!cpu_online(i))
1975+
/* If the cpu isn't present, the cpu is mapped to first hctx */
1976+
if (!cpu_present(i))
19801977
continue;
19811978

19821979
hctx = blk_mq_map_queue(q, i);
@@ -2019,8 +2016,7 @@ static void blk_mq_free_map_and_requests(struct blk_mq_tag_set *set,
20192016
}
20202017
}
20212018

2022-
static void blk_mq_map_swqueue(struct request_queue *q,
2023-
const struct cpumask *online_mask)
2019+
static void blk_mq_map_swqueue(struct request_queue *q)
20242020
{
20252021
unsigned int i, hctx_idx;
20262022
struct blk_mq_hw_ctx *hctx;
@@ -2038,13 +2034,11 @@ static void blk_mq_map_swqueue(struct request_queue *q,
20382034
}
20392035

20402036
/*
2041-
* Map software to hardware queues
2037+
* Map software to hardware queues.
2038+
*
2039+
* If the cpu isn't present, the cpu is mapped to first hctx.
20422040
*/
2043-
for_each_possible_cpu(i) {
2044-
/* If the cpu isn't online, the cpu is mapped to first hctx */
2045-
if (!cpumask_test_cpu(i, online_mask))
2046-
continue;
2047-
2041+
for_each_present_cpu(i) {
20482042
hctx_idx = q->mq_map[i];
20492043
/* unmapped hw queue can be remapped after CPU topo changed */
20502044
if (!set->tags[hctx_idx] &&
@@ -2330,16 +2324,8 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
23302324
blk_queue_softirq_done(q, set->ops->complete);
23312325

23322326
blk_mq_init_cpu_queues(q, set->nr_hw_queues);
2333-
2334-
get_online_cpus();
2335-
mutex_lock(&all_q_mutex);
2336-
2337-
list_add_tail(&q->all_q_node, &all_q_list);
23382327
blk_mq_add_queue_tag_set(set, q);
2339-
blk_mq_map_swqueue(q, cpu_online_mask);
2340-
2341-
mutex_unlock(&all_q_mutex);
2342-
put_online_cpus();
2328+
blk_mq_map_swqueue(q);
23432329

23442330
if (!(set->flags & BLK_MQ_F_NO_SCHED)) {
23452331
int ret;
@@ -2365,18 +2351,12 @@ void blk_mq_free_queue(struct request_queue *q)
23652351
{
23662352
struct blk_mq_tag_set *set = q->tag_set;
23672353

2368-
mutex_lock(&all_q_mutex);
2369-
list_del_init(&q->all_q_node);
2370-
mutex_unlock(&all_q_mutex);
2371-
23722354
blk_mq_del_queue_tag_set(q);
2373-
23742355
blk_mq_exit_hw_queues(q, set, set->nr_hw_queues);
23752356
}
23762357

23772358
/* Basically redo blk_mq_init_queue with queue frozen */
2378-
static void blk_mq_queue_reinit(struct request_queue *q,
2379-
const struct cpumask *online_mask)
2359+
static void blk_mq_queue_reinit(struct request_queue *q)
23802360
{
23812361
WARN_ON_ONCE(!atomic_read(&q->mq_freeze_depth));
23822362

@@ -2389,76 +2369,12 @@ static void blk_mq_queue_reinit(struct request_queue *q,
23892369
* involves free and re-allocate memory, worthy doing?)
23902370
*/
23912371

2392-
blk_mq_map_swqueue(q, online_mask);
2372+
blk_mq_map_swqueue(q);
23932373

23942374
blk_mq_sysfs_register(q);
23952375
blk_mq_debugfs_register_hctxs(q);
23962376
}
23972377

2398-
/*
2399-
* New online cpumask which is going to be set in this hotplug event.
2400-
* Declare this cpumasks as global as cpu-hotplug operation is invoked
2401-
* one-by-one and dynamically allocating this could result in a failure.
2402-
*/
2403-
static struct cpumask cpuhp_online_new;
2404-
2405-
static void blk_mq_queue_reinit_work(void)
2406-
{
2407-
struct request_queue *q;
2408-
2409-
mutex_lock(&all_q_mutex);
2410-
/*
2411-
* We need to freeze and reinit all existing queues. Freezing
2412-
* involves synchronous wait for an RCU grace period and doing it
2413-
* one by one may take a long time. Start freezing all queues in
2414-
* one swoop and then wait for the completions so that freezing can
2415-
* take place in parallel.
2416-
*/
2417-
list_for_each_entry(q, &all_q_list, all_q_node)
2418-
blk_freeze_queue_start(q);
2419-
list_for_each_entry(q, &all_q_list, all_q_node)
2420-
blk_mq_freeze_queue_wait(q);
2421-
2422-
list_for_each_entry(q, &all_q_list, all_q_node)
2423-
blk_mq_queue_reinit(q, &cpuhp_online_new);
2424-
2425-
list_for_each_entry(q, &all_q_list, all_q_node)
2426-
blk_mq_unfreeze_queue(q);
2427-
2428-
mutex_unlock(&all_q_mutex);
2429-
}
2430-
2431-
static int blk_mq_queue_reinit_dead(unsigned int cpu)
2432-
{
2433-
cpumask_copy(&cpuhp_online_new, cpu_online_mask);
2434-
blk_mq_queue_reinit_work();
2435-
return 0;
2436-
}
2437-
2438-
/*
2439-
* Before hotadded cpu starts handling requests, new mappings must be
2440-
* established. Otherwise, these requests in hw queue might never be
2441-
* dispatched.
2442-
*
2443-
* For example, there is a single hw queue (hctx) and two CPU queues (ctx0
2444-
* for CPU0, and ctx1 for CPU1).
2445-
*
2446-
* Now CPU1 is just onlined and a request is inserted into ctx1->rq_list
2447-
* and set bit0 in pending bitmap as ctx1->index_hw is still zero.
2448-
*
2449-
* And then while running hw queue, blk_mq_flush_busy_ctxs() finds bit0 is set
2450-
* in pending bitmap and tries to retrieve requests in hctx->ctxs[0]->rq_list.
2451-
* But htx->ctxs[0] is a pointer to ctx0, so the request in ctx1->rq_list is
2452-
* ignored.
2453-
*/
2454-
static int blk_mq_queue_reinit_prepare(unsigned int cpu)
2455-
{
2456-
cpumask_copy(&cpuhp_online_new, cpu_online_mask);
2457-
cpumask_set_cpu(cpu, &cpuhp_online_new);
2458-
blk_mq_queue_reinit_work();
2459-
return 0;
2460-
}
2461-
24622378
static int __blk_mq_alloc_rq_maps(struct blk_mq_tag_set *set)
24632379
{
24642380
int i;
@@ -2669,7 +2585,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
26692585
blk_mq_update_queue_map(set);
26702586
list_for_each_entry(q, &set->tag_list, tag_set_list) {
26712587
blk_mq_realloc_hw_ctxs(set, q);
2672-
blk_mq_queue_reinit(q, cpu_online_mask);
2588+
blk_mq_queue_reinit(q);
26732589
}
26742590

26752591
list_for_each_entry(q, &set->tag_list, tag_set_list)
@@ -2885,24 +2801,10 @@ bool blk_mq_poll(struct request_queue *q, blk_qc_t cookie)
28852801
}
28862802
EXPORT_SYMBOL_GPL(blk_mq_poll);
28872803

2888-
void blk_mq_disable_hotplug(void)
2889-
{
2890-
mutex_lock(&all_q_mutex);
2891-
}
2892-
2893-
void blk_mq_enable_hotplug(void)
2894-
{
2895-
mutex_unlock(&all_q_mutex);
2896-
}
2897-
28982804
static int __init blk_mq_init(void)
28992805
{
29002806
cpuhp_setup_state_multi(CPUHP_BLK_MQ_DEAD, "block/mq:dead", NULL,
29012807
blk_mq_hctx_notify_dead);
2902-
2903-
cpuhp_setup_state_nocalls(CPUHP_BLK_MQ_PREPARE, "block/mq:prepare",
2904-
blk_mq_queue_reinit_prepare,
2905-
blk_mq_queue_reinit_dead);
29062808
return 0;
29072809
}
29082810
subsys_initcall(blk_mq_init);

block/blk-mq.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@ void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
5656
bool at_head);
5757
void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx,
5858
struct list_head *list);
59-
/*
60-
* CPU hotplug helpers
61-
*/
62-
void blk_mq_enable_hotplug(void);
63-
void blk_mq_disable_hotplug(void);
6459

6560
/*
6661
* CPU -> queue mappings

include/linux/cpuhotplug.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ enum cpuhp_state {
5858
CPUHP_XEN_EVTCHN_PREPARE,
5959
CPUHP_ARM_SHMOBILE_SCU_PREPARE,
6060
CPUHP_SH_SH3X_PREPARE,
61-
CPUHP_BLK_MQ_PREPARE,
6261
CPUHP_NET_FLOW_PREPARE,
6362
CPUHP_TOPOLOGY_PREPARE,
6463
CPUHP_NET_IUCV_PREPARE,

0 commit comments

Comments
 (0)