aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2015-03-11 15:01:09 -0400
committerMike Snitzer <snitzer@redhat.com>2015-04-15 12:10:17 -0400
commit17e149b8f73ba116e71e25930dd6f2eb3828792d (patch)
tree6407112dbb113ffeebfd0620df27d4f67cd27ed1
parent022333427a8aa4ccb318a9db90cea4e69ca1826b (diff)
dm: add 'use_blk_mq' module param and expose in per-device ro sysfs attr
Request-based DM's blk-mq support defaults to off; but a user can easily change the default using the dm_mod.use_blk_mq module/boot option. Also, you can check what mode a given request-based DM device is using with: cat /sys/block/dm-X/dm/use_blk_mq This change enabled further cleanup and reduced work (e.g. the md->io_pool and md->rq_pool isn't created if using blk-mq). Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--Documentation/ABI/testing/sysfs-block-dm8
-rw-r--r--drivers/md/Kconfig11
-rw-r--r--drivers/md/dm-sysfs.c9
-rw-r--r--drivers/md/dm-table.c6
-rw-r--r--drivers/md/dm.c53
-rw-r--r--drivers/md/dm.h5
6 files changed, 76 insertions, 16 deletions
diff --git a/Documentation/ABI/testing/sysfs-block-dm b/Documentation/ABI/testing/sysfs-block-dm
index ac4b6fe245d9..f9f2339b9a0a 100644
--- a/Documentation/ABI/testing/sysfs-block-dm
+++ b/Documentation/ABI/testing/sysfs-block-dm
@@ -37,3 +37,11 @@ Description: Allow control over how long a request that is a
37 accounting. This attribute is not applicable to 37 accounting. This attribute is not applicable to
38 bio-based DM devices so it will only ever report 0 for 38 bio-based DM devices so it will only ever report 0 for
39 them. 39 them.
40
41What: /sys/block/dm-<num>/dm/use_blk_mq
42Date: March 2015
43KernelVersion: 4.1
44Contact: dm-devel@redhat.com
45Description: Request-based Device-mapper blk-mq I/O path mode.
46 Contains the value 1 if the device is using blk-mq.
47 Otherwise it contains 0. Read-only attribute.
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 63e05e32b462..109f9dcc9cab 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -196,6 +196,17 @@ config BLK_DEV_DM
196 196
197 If unsure, say N. 197 If unsure, say N.
198 198
199config DM_MQ_DEFAULT
200 bool "request-based DM: use blk-mq I/O path by default"
201 depends on BLK_DEV_DM
202 ---help---
203 This option enables the blk-mq based I/O path for request-based
204 DM devices by default. With the option the dm_mod.use_blk_mq
205 module/boot option defaults to Y, without it to N, but it can
206 still be overriden either way.
207
208 If unsure say N.
209
199config DM_DEBUG 210config DM_DEBUG
200 bool "Device mapper debugging support" 211 bool "Device mapper debugging support"
201 depends on BLK_DEV_DM 212 depends on BLK_DEV_DM
diff --git a/drivers/md/dm-sysfs.c b/drivers/md/dm-sysfs.c
index f5bb3944f75e..7e818f5f1dc4 100644
--- a/drivers/md/dm-sysfs.c
+++ b/drivers/md/dm-sysfs.c
@@ -89,15 +89,24 @@ static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf)
89 return strlen(buf); 89 return strlen(buf);
90} 90}
91 91
92static ssize_t dm_attr_use_blk_mq_show(struct mapped_device *md, char *buf)
93{
94 sprintf(buf, "%d\n", dm_use_blk_mq(md));
95
96 return strlen(buf);
97}
98
92static DM_ATTR_RO(name); 99static DM_ATTR_RO(name);
93static DM_ATTR_RO(uuid); 100static DM_ATTR_RO(uuid);
94static DM_ATTR_RO(suspended); 101static DM_ATTR_RO(suspended);
102static DM_ATTR_RO(use_blk_mq);
95static DM_ATTR_RW(rq_based_seq_io_merge_deadline); 103static DM_ATTR_RW(rq_based_seq_io_merge_deadline);
96 104
97static struct attribute *dm_attrs[] = { 105static struct attribute *dm_attrs[] = {
98 &dm_attr_name.attr, 106 &dm_attr_name.attr,
99 &dm_attr_uuid.attr, 107 &dm_attr_uuid.attr,
100 &dm_attr_suspended.attr, 108 &dm_attr_suspended.attr,
109 &dm_attr_use_blk_mq.attr,
101 &dm_attr_rq_based_seq_io_merge_deadline.attr, 110 &dm_attr_rq_based_seq_io_merge_deadline.attr,
102 NULL, 111 NULL,
103}; 112};
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 66600cab9fa5..8d025f33de92 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -940,7 +940,7 @@ bool dm_table_mq_request_based(struct dm_table *t)
940 return dm_table_get_type(t) == DM_TYPE_MQ_REQUEST_BASED; 940 return dm_table_get_type(t) == DM_TYPE_MQ_REQUEST_BASED;
941} 941}
942 942
943static int dm_table_alloc_md_mempools(struct dm_table *t) 943static int dm_table_alloc_md_mempools(struct dm_table *t, struct mapped_device *md)
944{ 944{
945 unsigned type = dm_table_get_type(t); 945 unsigned type = dm_table_get_type(t);
946 unsigned per_bio_data_size = 0; 946 unsigned per_bio_data_size = 0;
@@ -958,7 +958,7 @@ static int dm_table_alloc_md_mempools(struct dm_table *t)
958 per_bio_data_size = max(per_bio_data_size, tgt->per_bio_data_size); 958 per_bio_data_size = max(per_bio_data_size, tgt->per_bio_data_size);
959 } 959 }
960 960
961 t->mempools = dm_alloc_md_mempools(type, t->integrity_supported, per_bio_data_size); 961 t->mempools = dm_alloc_md_mempools(md, type, t->integrity_supported, per_bio_data_size);
962 if (!t->mempools) 962 if (!t->mempools)
963 return -ENOMEM; 963 return -ENOMEM;
964 964
@@ -1128,7 +1128,7 @@ int dm_table_complete(struct dm_table *t)
1128 return r; 1128 return r;
1129 } 1129 }
1130 1130
1131 r = dm_table_alloc_md_mempools(t); 1131 r = dm_table_alloc_md_mempools(t, t->md);
1132 if (r) 1132 if (r)
1133 DMERR("unable to allocate mempools"); 1133 DMERR("unable to allocate mempools");
1134 1134
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 55cadb1a2735..944cdb322708 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -228,8 +228,20 @@ struct mapped_device {
228 228
229 /* for blk-mq request-based DM support */ 229 /* for blk-mq request-based DM support */
230 struct blk_mq_tag_set tag_set; 230 struct blk_mq_tag_set tag_set;
231 bool use_blk_mq;
231}; 232};
232 233
234#ifdef CONFIG_DM_MQ_DEFAULT
235static bool use_blk_mq = true;
236#else
237static bool use_blk_mq = false;
238#endif
239
240bool dm_use_blk_mq(struct mapped_device *md)
241{
242 return md->use_blk_mq;
243}
244
233/* 245/*
234 * For mempools pre-allocation at the table loading time. 246 * For mempools pre-allocation at the table loading time.
235 */ 247 */
@@ -2034,7 +2046,7 @@ ssize_t dm_attr_rq_based_seq_io_merge_deadline_store(struct mapped_device *md,
2034{ 2046{
2035 unsigned deadline; 2047 unsigned deadline;
2036 2048
2037 if (!dm_request_based(md)) 2049 if (!dm_request_based(md) || md->use_blk_mq)
2038 return count; 2050 return count;
2039 2051
2040 if (kstrtouint(buf, 10, &deadline)) 2052 if (kstrtouint(buf, 10, &deadline))
@@ -2222,6 +2234,7 @@ static void dm_init_md_queue(struct mapped_device *md)
2222 2234
2223static void dm_init_old_md_queue(struct mapped_device *md) 2235static void dm_init_old_md_queue(struct mapped_device *md)
2224{ 2236{
2237 md->use_blk_mq = false;
2225 dm_init_md_queue(md); 2238 dm_init_md_queue(md);
2226 2239
2227 /* 2240 /*
@@ -2263,6 +2276,7 @@ static struct mapped_device *alloc_dev(int minor)
2263 if (r < 0) 2276 if (r < 0)
2264 goto bad_io_barrier; 2277 goto bad_io_barrier;
2265 2278
2279 md->use_blk_mq = use_blk_mq;
2266 md->type = DM_TYPE_NONE; 2280 md->type = DM_TYPE_NONE;
2267 mutex_init(&md->suspend_lock); 2281 mutex_init(&md->suspend_lock);
2268 mutex_init(&md->type_lock); 2282 mutex_init(&md->type_lock);
@@ -2349,7 +2363,6 @@ static void unlock_fs(struct mapped_device *md);
2349static void free_dev(struct mapped_device *md) 2363static void free_dev(struct mapped_device *md)
2350{ 2364{
2351 int minor = MINOR(disk_devt(md->disk)); 2365 int minor = MINOR(disk_devt(md->disk));
2352 bool using_blk_mq = !!md->queue->mq_ops;
2353 2366
2354 unlock_fs(md); 2367 unlock_fs(md);
2355 destroy_workqueue(md->wq); 2368 destroy_workqueue(md->wq);
@@ -2375,7 +2388,7 @@ static void free_dev(struct mapped_device *md)
2375 del_gendisk(md->disk); 2388 del_gendisk(md->disk);
2376 put_disk(md->disk); 2389 put_disk(md->disk);
2377 blk_cleanup_queue(md->queue); 2390 blk_cleanup_queue(md->queue);
2378 if (using_blk_mq) 2391 if (md->use_blk_mq)
2379 blk_mq_free_tag_set(&md->tag_set); 2392 blk_mq_free_tag_set(&md->tag_set);
2380 bdput(md->bdev); 2393 bdput(md->bdev);
2381 free_minor(minor); 2394 free_minor(minor);
@@ -2388,7 +2401,7 @@ static void __bind_mempools(struct mapped_device *md, struct dm_table *t)
2388{ 2401{
2389 struct dm_md_mempools *p = dm_table_get_md_mempools(t); 2402 struct dm_md_mempools *p = dm_table_get_md_mempools(t);
2390 2403
2391 if (md->io_pool && md->bs) { 2404 if (md->bs) {
2392 /* The md already has necessary mempools. */ 2405 /* The md already has necessary mempools. */
2393 if (dm_table_get_type(t) == DM_TYPE_BIO_BASED) { 2406 if (dm_table_get_type(t) == DM_TYPE_BIO_BASED) {
2394 /* 2407 /*
@@ -2798,13 +2811,21 @@ out_tag_set:
2798 return err; 2811 return err;
2799} 2812}
2800 2813
2814static unsigned filter_md_type(unsigned type, struct mapped_device *md)
2815{
2816 if (type == DM_TYPE_BIO_BASED)
2817 return type;
2818
2819 return !md->use_blk_mq ? DM_TYPE_REQUEST_BASED : DM_TYPE_MQ_REQUEST_BASED;
2820}
2821
2801/* 2822/*
2802 * Setup the DM device's queue based on md's type 2823 * Setup the DM device's queue based on md's type
2803 */ 2824 */
2804int dm_setup_md_queue(struct mapped_device *md) 2825int dm_setup_md_queue(struct mapped_device *md)
2805{ 2826{
2806 int r; 2827 int r;
2807 unsigned md_type = dm_get_md_type(md); 2828 unsigned md_type = filter_md_type(dm_get_md_type(md), md);
2808 2829
2809 switch (md_type) { 2830 switch (md_type) {
2810 case DM_TYPE_REQUEST_BASED: 2831 case DM_TYPE_REQUEST_BASED:
@@ -3509,16 +3530,19 @@ int dm_noflush_suspending(struct dm_target *ti)
3509} 3530}
3510EXPORT_SYMBOL_GPL(dm_noflush_suspending); 3531EXPORT_SYMBOL_GPL(dm_noflush_suspending);
3511 3532
3512struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity, unsigned per_bio_data_size) 3533struct dm_md_mempools *dm_alloc_md_mempools(struct mapped_device *md, unsigned type,
3534 unsigned integrity, unsigned per_bio_data_size)
3513{ 3535{
3514 struct dm_md_mempools *pools = kzalloc(sizeof(*pools), GFP_KERNEL); 3536 struct dm_md_mempools *pools = kzalloc(sizeof(*pools), GFP_KERNEL);
3515 struct kmem_cache *cachep; 3537 struct kmem_cache *cachep = NULL;
3516 unsigned int pool_size = 0; 3538 unsigned int pool_size = 0;
3517 unsigned int front_pad; 3539 unsigned int front_pad;
3518 3540
3519 if (!pools) 3541 if (!pools)
3520 return NULL; 3542 return NULL;
3521 3543
3544 type = filter_md_type(type, md);
3545
3522 switch (type) { 3546 switch (type) {
3523 case DM_TYPE_BIO_BASED: 3547 case DM_TYPE_BIO_BASED:
3524 cachep = _io_cache; 3548 cachep = _io_cache;
@@ -3526,13 +3550,13 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity, u
3526 front_pad = roundup(per_bio_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone); 3550 front_pad = roundup(per_bio_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone);
3527 break; 3551 break;
3528 case DM_TYPE_REQUEST_BASED: 3552 case DM_TYPE_REQUEST_BASED:
3553 cachep = _rq_tio_cache;
3529 pool_size = dm_get_reserved_rq_based_ios(); 3554 pool_size = dm_get_reserved_rq_based_ios();
3530 pools->rq_pool = mempool_create_slab_pool(pool_size, _rq_cache); 3555 pools->rq_pool = mempool_create_slab_pool(pool_size, _rq_cache);
3531 if (!pools->rq_pool) 3556 if (!pools->rq_pool)
3532 goto out; 3557 goto out;
3533 /* fall through to setup remaining rq-based pools */ 3558 /* fall through to setup remaining rq-based pools */
3534 case DM_TYPE_MQ_REQUEST_BASED: 3559 case DM_TYPE_MQ_REQUEST_BASED:
3535 cachep = _rq_tio_cache;
3536 if (!pool_size) 3560 if (!pool_size)
3537 pool_size = dm_get_reserved_rq_based_ios(); 3561 pool_size = dm_get_reserved_rq_based_ios();
3538 front_pad = offsetof(struct dm_rq_clone_bio_info, clone); 3562 front_pad = offsetof(struct dm_rq_clone_bio_info, clone);
@@ -3540,12 +3564,14 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity, u
3540 WARN_ON(per_bio_data_size != 0); 3564 WARN_ON(per_bio_data_size != 0);
3541 break; 3565 break;
3542 default: 3566 default:
3543 goto out; 3567 BUG();
3544 } 3568 }
3545 3569
3546 pools->io_pool = mempool_create_slab_pool(pool_size, cachep); 3570 if (cachep) {
3547 if (!pools->io_pool) 3571 pools->io_pool = mempool_create_slab_pool(pool_size, cachep);
3548 goto out; 3572 if (!pools->io_pool)
3573 goto out;
3574 }
3549 3575
3550 pools->bs = bioset_create_nobvec(pool_size, front_pad); 3576 pools->bs = bioset_create_nobvec(pool_size, front_pad);
3551 if (!pools->bs) 3577 if (!pools->bs)
@@ -3602,6 +3628,9 @@ MODULE_PARM_DESC(reserved_bio_based_ios, "Reserved IOs in bio-based mempools");
3602module_param(reserved_rq_based_ios, uint, S_IRUGO | S_IWUSR); 3628module_param(reserved_rq_based_ios, uint, S_IRUGO | S_IWUSR);
3603MODULE_PARM_DESC(reserved_rq_based_ios, "Reserved IOs in request-based mempools"); 3629MODULE_PARM_DESC(reserved_rq_based_ios, "Reserved IOs in request-based mempools");
3604 3630
3631module_param(use_blk_mq, bool, S_IRUGO | S_IWUSR);
3632MODULE_PARM_DESC(use_blk_mq, "Use block multiqueue for request-based DM devices");
3633
3605MODULE_DESCRIPTION(DM_NAME " driver"); 3634MODULE_DESCRIPTION(DM_NAME " driver");
3606MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); 3635MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
3607MODULE_LICENSE("GPL"); 3636MODULE_LICENSE("GPL");
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 5522422cc6c4..6123c2bf9150 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -211,6 +211,8 @@ int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
211void dm_internal_suspend(struct mapped_device *md); 211void dm_internal_suspend(struct mapped_device *md);
212void dm_internal_resume(struct mapped_device *md); 212void dm_internal_resume(struct mapped_device *md);
213 213
214bool dm_use_blk_mq(struct mapped_device *md);
215
214int dm_io_init(void); 216int dm_io_init(void);
215void dm_io_exit(void); 217void dm_io_exit(void);
216 218
@@ -220,7 +222,8 @@ void dm_kcopyd_exit(void);
220/* 222/*
221 * Mempool operations 223 * Mempool operations
222 */ 224 */
223struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity, unsigned per_bio_data_size); 225struct dm_md_mempools *dm_alloc_md_mempools(struct mapped_device *md, unsigned type,
226 unsigned integrity, unsigned per_bio_data_size);
224void dm_free_md_mempools(struct dm_md_mempools *pools); 227void dm_free_md_mempools(struct dm_md_mempools *pools);
225 228
226/* 229/*