aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2011-03-17 06:11:05 -0400
committerJens Axboe <jaxboe@fusionio.com>2011-03-17 06:11:05 -0400
commita91a2785b200864aef2270ed6a3babac7a253a20 (patch)
tree3d21d7ef82ddabbdbfb74499d68a73f15adc819f
parent82f04ab47e1d94d78503591a7460b2cad9601ede (diff)
block: Require subsystems to explicitly allocate bio_set integrity mempool
MD and DM create a new bio_set for every metadevice. Each bio_set has an integrity mempool attached regardless of whether the metadevice is capable of passing integrity metadata. This is a waste of memory. Instead we defer the allocation decision to MD and DM since we know at metadevice creation time whether integrity passthrough is needed or not. Automatic integrity mempool allocation can then be removed from bioset_create() and we make an explicit integrity allocation for the fs_bio_set. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Reported-by: Zdenek Kabelac <zkabelac@redhat.com> Acked-by: Mike Snitzer <snizer@redhat.com> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
-rw-r--r--drivers/md/dm-table.c7
-rw-r--r--drivers/md/dm.c12
-rw-r--r--drivers/md/dm.h2
-rw-r--r--drivers/md/linear.c3
-rw-r--r--drivers/md/md.c8
-rw-r--r--drivers/md/multipath.c7
-rw-r--r--drivers/md/raid0.c3
-rw-r--r--drivers/md/raid1.c5
-rw-r--r--drivers/md/raid10.c7
-rw-r--r--fs/bio-integrity.c3
-rw-r--r--fs/bio.c6
11 files changed, 41 insertions, 22 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index f50a7b952257..416d4e258df6 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -55,6 +55,7 @@ struct dm_table {
55 struct dm_target *targets; 55 struct dm_target *targets;
56 56
57 unsigned discards_supported:1; 57 unsigned discards_supported:1;
58 unsigned integrity_supported:1;
58 59
59 /* 60 /*
60 * Indicates the rw permissions for the new logical 61 * Indicates the rw permissions for the new logical
@@ -859,7 +860,7 @@ int dm_table_alloc_md_mempools(struct dm_table *t)
859 return -EINVAL; 860 return -EINVAL;
860 } 861 }
861 862
862 t->mempools = dm_alloc_md_mempools(type); 863 t->mempools = dm_alloc_md_mempools(type, t->integrity_supported);
863 if (!t->mempools) 864 if (!t->mempools)
864 return -ENOMEM; 865 return -ENOMEM;
865 866
@@ -935,8 +936,10 @@ static int dm_table_prealloc_integrity(struct dm_table *t, struct mapped_device
935 struct dm_dev_internal *dd; 936 struct dm_dev_internal *dd;
936 937
937 list_for_each_entry(dd, devices, list) 938 list_for_each_entry(dd, devices, list)
938 if (bdev_get_integrity(dd->dm_dev.bdev)) 939 if (bdev_get_integrity(dd->dm_dev.bdev)) {
940 t->integrity_supported = 1;
939 return blk_integrity_register(dm_disk(md), NULL); 941 return blk_integrity_register(dm_disk(md), NULL);
942 }
940 943
941 return 0; 944 return 0;
942} 945}
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index d22b9905c168..88820704a191 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -2620,9 +2620,10 @@ int dm_noflush_suspending(struct dm_target *ti)
2620} 2620}
2621EXPORT_SYMBOL_GPL(dm_noflush_suspending); 2621EXPORT_SYMBOL_GPL(dm_noflush_suspending);
2622 2622
2623struct dm_md_mempools *dm_alloc_md_mempools(unsigned type) 2623struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity)
2624{ 2624{
2625 struct dm_md_mempools *pools = kmalloc(sizeof(*pools), GFP_KERNEL); 2625 struct dm_md_mempools *pools = kmalloc(sizeof(*pools), GFP_KERNEL);
2626 unsigned int pool_size = (type == DM_TYPE_BIO_BASED) ? 16 : MIN_IOS;
2626 2627
2627 if (!pools) 2628 if (!pools)
2628 return NULL; 2629 return NULL;
@@ -2639,13 +2640,18 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type)
2639 if (!pools->tio_pool) 2640 if (!pools->tio_pool)
2640 goto free_io_pool_and_out; 2641 goto free_io_pool_and_out;
2641 2642
2642 pools->bs = (type == DM_TYPE_BIO_BASED) ? 2643 pools->bs = bioset_create(pool_size, 0);
2643 bioset_create(16, 0) : bioset_create(MIN_IOS, 0);
2644 if (!pools->bs) 2644 if (!pools->bs)
2645 goto free_tio_pool_and_out; 2645 goto free_tio_pool_and_out;
2646 2646
2647 if (integrity && bioset_integrity_create(pools->bs, pool_size))
2648 goto free_bioset_and_out;
2649
2647 return pools; 2650 return pools;
2648 2651
2652free_bioset_and_out:
2653 bioset_free(pools->bs);
2654
2649free_tio_pool_and_out: 2655free_tio_pool_and_out:
2650 mempool_destroy(pools->tio_pool); 2656 mempool_destroy(pools->tio_pool);
2651 2657
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 0c2dd5f4af76..1aaf16746da8 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -149,7 +149,7 @@ void dm_kcopyd_exit(void);
149/* 149/*
150 * Mempool operations 150 * Mempool operations
151 */ 151 */
152struct dm_md_mempools *dm_alloc_md_mempools(unsigned type); 152struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity);
153void dm_free_md_mempools(struct dm_md_mempools *pools); 153void dm_free_md_mempools(struct dm_md_mempools *pools);
154 154
155#endif 155#endif
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 338804f8fb3b..abfb59a61ede 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -210,8 +210,7 @@ static int linear_run (mddev_t *mddev)
210 blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); 210 blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
211 mddev->queue->backing_dev_info.congested_fn = linear_congested; 211 mddev->queue->backing_dev_info.congested_fn = linear_congested;
212 mddev->queue->backing_dev_info.congested_data = mddev; 212 mddev->queue->backing_dev_info.congested_data = mddev;
213 md_integrity_register(mddev); 213 return md_integrity_register(mddev);
214 return 0;
215} 214}
216 215
217static void free_conf(struct rcu_head *head) 216static void free_conf(struct rcu_head *head)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 86ba66c0b28a..1876761f1828 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1803,8 +1803,12 @@ int md_integrity_register(mddev_t *mddev)
1803 mdname(mddev)); 1803 mdname(mddev));
1804 return -EINVAL; 1804 return -EINVAL;
1805 } 1805 }
1806 printk(KERN_NOTICE "md: data integrity on %s enabled\n", 1806 printk(KERN_NOTICE "md: data integrity enabled on %s\n", mdname(mddev));
1807 mdname(mddev)); 1807 if (bioset_integrity_create(mddev->bio_set, BIO_POOL_SIZE)) {
1808 printk(KERN_ERR "md: failed to create integrity pool for %s\n",
1809 mdname(mddev));
1810 return -EINVAL;
1811 }
1808 return 0; 1812 return 0;
1809} 1813}
1810EXPORT_SYMBOL(md_integrity_register); 1814EXPORT_SYMBOL(md_integrity_register);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 5e694b151c30..c35890990985 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -315,7 +315,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
315 p->rdev = rdev; 315 p->rdev = rdev;
316 goto abort; 316 goto abort;
317 } 317 }
318 md_integrity_register(mddev); 318 err = md_integrity_register(mddev);
319 } 319 }
320abort: 320abort:
321 321
@@ -489,7 +489,10 @@ static int multipath_run (mddev_t *mddev)
489 489
490 mddev->queue->backing_dev_info.congested_fn = multipath_congested; 490 mddev->queue->backing_dev_info.congested_fn = multipath_congested;
491 mddev->queue->backing_dev_info.congested_data = mddev; 491 mddev->queue->backing_dev_info.congested_data = mddev;
492 md_integrity_register(mddev); 492
493 if (md_integrity_register(mddev))
494 goto out_free_conf;
495
493 return 0; 496 return 0;
494 497
495out_free_conf: 498out_free_conf:
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 95916fd6394a..e86bf3682e1e 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -379,8 +379,7 @@ static int raid0_run(mddev_t *mddev)
379 379
380 blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec); 380 blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec);
381 dump_zones(mddev); 381 dump_zones(mddev);
382 md_integrity_register(mddev); 382 return md_integrity_register(mddev);
383 return 0;
384} 383}
385 384
386static int raid0_stop(mddev_t *mddev) 385static int raid0_stop(mddev_t *mddev)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 8f34ad5c478b..c2a21ae56d97 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1132,7 +1132,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
1132 p->rdev = rdev; 1132 p->rdev = rdev;
1133 goto abort; 1133 goto abort;
1134 } 1134 }
1135 md_integrity_register(mddev); 1135 err = md_integrity_register(mddev);
1136 } 1136 }
1137abort: 1137abort:
1138 1138
@@ -2017,8 +2017,7 @@ static int run(mddev_t *mddev)
2017 2017
2018 mddev->queue->backing_dev_info.congested_fn = raid1_congested; 2018 mddev->queue->backing_dev_info.congested_fn = raid1_congested;
2019 mddev->queue->backing_dev_info.congested_data = mddev; 2019 mddev->queue->backing_dev_info.congested_data = mddev;
2020 md_integrity_register(mddev); 2020 return md_integrity_register(mddev);
2021 return 0;
2022} 2021}
2023 2022
2024static int stop(mddev_t *mddev) 2023static int stop(mddev_t *mddev)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c0d0f5f7e407..f7b62370b374 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1188,7 +1188,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
1188 p->rdev = rdev; 1188 p->rdev = rdev;
1189 goto abort; 1189 goto abort;
1190 } 1190 }
1191 md_integrity_register(mddev); 1191 err = md_integrity_register(mddev);
1192 } 1192 }
1193abort: 1193abort:
1194 1194
@@ -2343,7 +2343,10 @@ static int run(mddev_t *mddev)
2343 2343
2344 if (conf->near_copies < conf->raid_disks) 2344 if (conf->near_copies < conf->raid_disks)
2345 blk_queue_merge_bvec(mddev->queue, raid10_mergeable_bvec); 2345 blk_queue_merge_bvec(mddev->queue, raid10_mergeable_bvec);
2346 md_integrity_register(mddev); 2346
2347 if (md_integrity_register(mddev))
2348 goto out_free_conf;
2349
2347 return 0; 2350 return 0;
2348 2351
2349out_free_conf: 2352out_free_conf:
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index e49cce234c65..9c5e6b2cd11a 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -761,6 +761,9 @@ int bioset_integrity_create(struct bio_set *bs, int pool_size)
761{ 761{
762 unsigned int max_slab = vecs_to_idx(BIO_MAX_PAGES); 762 unsigned int max_slab = vecs_to_idx(BIO_MAX_PAGES);
763 763
764 if (bs->bio_integrity_pool)
765 return 0;
766
764 bs->bio_integrity_pool = 767 bs->bio_integrity_pool =
765 mempool_create_slab_pool(pool_size, bip_slab[max_slab].slab); 768 mempool_create_slab_pool(pool_size, bip_slab[max_slab].slab);
766 769
diff --git a/fs/bio.c b/fs/bio.c
index 5694b756ed01..85e2eabb1f81 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1636,9 +1636,6 @@ struct bio_set *bioset_create(unsigned int pool_size, unsigned int front_pad)
1636 if (!bs->bio_pool) 1636 if (!bs->bio_pool)
1637 goto bad; 1637 goto bad;
1638 1638
1639 if (bioset_integrity_create(bs, pool_size))
1640 goto bad;
1641
1642 if (!biovec_create_pools(bs, pool_size)) 1639 if (!biovec_create_pools(bs, pool_size))
1643 return bs; 1640 return bs;
1644 1641
@@ -1682,6 +1679,9 @@ static int __init init_bio(void)
1682 if (!fs_bio_set) 1679 if (!fs_bio_set)
1683 panic("bio: can't allocate bios\n"); 1680 panic("bio: can't allocate bios\n");
1684 1681
1682 if (bioset_integrity_create(fs_bio_set, BIO_POOL_SIZE))
1683 panic("bio: can't create integrity pool\n");
1684
1685 bio_split_pool = mempool_create_kmalloc_pool(BIO_SPLIT_ENTRIES, 1685 bio_split_pool = mempool_create_kmalloc_pool(BIO_SPLIT_ENTRIES,
1686 sizeof(struct bio_pair)); 1686 sizeof(struct bio_pair));
1687 if (!bio_split_pool) 1687 if (!bio_split_pool)