diff options
-rw-r--r-- | block/blk-mq-sysfs.c | 6 | ||||
-rw-r--r-- | block/blk-mq.c | 6 | ||||
-rw-r--r-- | block/blk-sysfs.c | 11 | ||||
-rw-r--r-- | include/linux/blk-mq.h | 1 |
4 files changed, 21 insertions, 3 deletions
diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c index ed5217867555..371d8800b48a 100644 --- a/block/blk-mq-sysfs.c +++ b/block/blk-mq-sysfs.c | |||
@@ -402,6 +402,12 @@ static void blk_mq_sysfs_init(struct request_queue *q) | |||
402 | } | 402 | } |
403 | } | 403 | } |
404 | 404 | ||
405 | /* see blk_register_queue() */ | ||
406 | void blk_mq_finish_init(struct request_queue *q) | ||
407 | { | ||
408 | percpu_ref_switch_to_percpu(&q->mq_usage_counter); | ||
409 | } | ||
410 | |||
405 | int blk_mq_register_disk(struct gendisk *disk) | 411 | int blk_mq_register_disk(struct gendisk *disk) |
406 | { | 412 | { |
407 | struct device *dev = disk_to_dev(disk); | 413 | struct device *dev = disk_to_dev(disk); |
diff --git a/block/blk-mq.c b/block/blk-mq.c index d85fe01c44ef..38f4a165640d 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -1795,8 +1795,12 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set) | |||
1795 | if (!q) | 1795 | if (!q) |
1796 | goto err_hctxs; | 1796 | goto err_hctxs; |
1797 | 1797 | ||
1798 | /* | ||
1799 | * Init percpu_ref in atomic mode so that it's faster to shutdown. | ||
1800 | * See blk_register_queue() for details. | ||
1801 | */ | ||
1798 | if (percpu_ref_init(&q->mq_usage_counter, blk_mq_usage_counter_release, | 1802 | if (percpu_ref_init(&q->mq_usage_counter, blk_mq_usage_counter_release, |
1799 | 0, GFP_KERNEL)) | 1803 | PERCPU_REF_INIT_ATOMIC, GFP_KERNEL)) |
1800 | goto err_map; | 1804 | goto err_map; |
1801 | 1805 | ||
1802 | setup_timer(&q->timeout, blk_mq_rq_timer, (unsigned long) q); | 1806 | setup_timer(&q->timeout, blk_mq_rq_timer, (unsigned long) q); |
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 17f5c84ce7bf..521ae9089c50 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
@@ -551,12 +551,19 @@ int blk_register_queue(struct gendisk *disk) | |||
551 | return -ENXIO; | 551 | return -ENXIO; |
552 | 552 | ||
553 | /* | 553 | /* |
554 | * Initialization must be complete by now. Finish the initial | 554 | * SCSI probing may synchronously create and destroy a lot of |
555 | * bypass from queue allocation. | 555 | * request_queues for non-existent devices. Shutting down a fully |
556 | * functional queue takes measureable wallclock time as RCU grace | ||
557 | * periods are involved. To avoid excessive latency in these | ||
558 | * cases, a request_queue starts out in a degraded mode which is | ||
559 | * faster to shut down and is made fully functional here as | ||
560 | * request_queues for non-existent devices never get registered. | ||
556 | */ | 561 | */ |
557 | if (!blk_queue_init_done(q)) { | 562 | if (!blk_queue_init_done(q)) { |
558 | queue_flag_set_unlocked(QUEUE_FLAG_INIT_DONE, q); | 563 | queue_flag_set_unlocked(QUEUE_FLAG_INIT_DONE, q); |
559 | blk_queue_bypass_end(q); | 564 | blk_queue_bypass_end(q); |
565 | if (q->mq_ops) | ||
566 | blk_mq_finish_init(q); | ||
560 | } | 567 | } |
561 | 568 | ||
562 | ret = blk_trace_init_sysfs(dev); | 569 | ret = blk_trace_init_sysfs(dev); |
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index a1e31f274fcd..c13a0c09faea 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h | |||
@@ -140,6 +140,7 @@ enum { | |||
140 | }; | 140 | }; |
141 | 141 | ||
142 | struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *); | 142 | struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *); |
143 | void blk_mq_finish_init(struct request_queue *q); | ||
143 | int blk_mq_register_disk(struct gendisk *); | 144 | int blk_mq_register_disk(struct gendisk *); |
144 | void blk_mq_unregister_disk(struct gendisk *); | 145 | void blk_mq_unregister_disk(struct gendisk *); |
145 | 146 | ||