Commit a91a2785b200864aef2270ed6a3babac7a253a20
Committed by
Jens Axboe
1 parent
82f04ab47e
Exists in
master
and in
20 other branches
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>
Showing 11 changed files with 41 additions and 22 deletions Side-by-side Diff
drivers/md/dm-table.c
... | ... | @@ -55,6 +55,7 @@ |
55 | 55 | struct dm_target *targets; |
56 | 56 | |
57 | 57 | unsigned discards_supported:1; |
58 | + unsigned integrity_supported:1; | |
58 | 59 | |
59 | 60 | /* |
60 | 61 | * Indicates the rw permissions for the new logical |
... | ... | @@ -859,7 +860,7 @@ |
859 | 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 | 864 | if (!t->mempools) |
864 | 865 | return -ENOMEM; |
865 | 866 | |
866 | 867 | |
... | ... | @@ -935,8 +936,10 @@ |
935 | 936 | struct dm_dev_internal *dd; |
936 | 937 | |
937 | 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 | 941 | return blk_integrity_register(dm_disk(md), NULL); |
942 | + } | |
940 | 943 | |
941 | 944 | return 0; |
942 | 945 | } |
drivers/md/dm.c
... | ... | @@ -2620,9 +2620,10 @@ |
2620 | 2620 | } |
2621 | 2621 | EXPORT_SYMBOL_GPL(dm_noflush_suspending); |
2622 | 2622 | |
2623 | -struct dm_md_mempools *dm_alloc_md_mempools(unsigned type) | |
2623 | +struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity) | |
2624 | 2624 | { |
2625 | 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 | 2628 | if (!pools) |
2628 | 2629 | return NULL; |
2629 | 2630 | |
2630 | 2631 | |
... | ... | @@ -2639,12 +2640,17 @@ |
2639 | 2640 | if (!pools->tio_pool) |
2640 | 2641 | goto free_io_pool_and_out; |
2641 | 2642 | |
2642 | - pools->bs = (type == DM_TYPE_BIO_BASED) ? | |
2643 | - bioset_create(16, 0) : bioset_create(MIN_IOS, 0); | |
2643 | + pools->bs = bioset_create(pool_size, 0); | |
2644 | 2644 | if (!pools->bs) |
2645 | 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 | 2650 | return pools; |
2651 | + | |
2652 | +free_bioset_and_out: | |
2653 | + bioset_free(pools->bs); | |
2648 | 2654 | |
2649 | 2655 | free_tio_pool_and_out: |
2650 | 2656 | mempool_destroy(pools->tio_pool); |
drivers/md/dm.h
... | ... | @@ -149,7 +149,7 @@ |
149 | 149 | /* |
150 | 150 | * Mempool operations |
151 | 151 | */ |
152 | -struct dm_md_mempools *dm_alloc_md_mempools(unsigned type); | |
152 | +struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity); | |
153 | 153 | void dm_free_md_mempools(struct dm_md_mempools *pools); |
154 | 154 | |
155 | 155 | #endif |
drivers/md/linear.c
... | ... | @@ -210,8 +210,7 @@ |
210 | 210 | blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); |
211 | 211 | mddev->queue->backing_dev_info.congested_fn = linear_congested; |
212 | 212 | mddev->queue->backing_dev_info.congested_data = mddev; |
213 | - md_integrity_register(mddev); | |
214 | - return 0; | |
213 | + return md_integrity_register(mddev); | |
215 | 214 | } |
216 | 215 | |
217 | 216 | static void free_conf(struct rcu_head *head) |
drivers/md/md.c
... | ... | @@ -1803,8 +1803,12 @@ |
1803 | 1803 | mdname(mddev)); |
1804 | 1804 | return -EINVAL; |
1805 | 1805 | } |
1806 | - printk(KERN_NOTICE "md: data integrity on %s enabled\n", | |
1807 | - mdname(mddev)); | |
1806 | + printk(KERN_NOTICE "md: data integrity enabled on %s\n", 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 | 1812 | return 0; |
1809 | 1813 | } |
1810 | 1814 | EXPORT_SYMBOL(md_integrity_register); |
drivers/md/multipath.c
... | ... | @@ -315,7 +315,7 @@ |
315 | 315 | p->rdev = rdev; |
316 | 316 | goto abort; |
317 | 317 | } |
318 | - md_integrity_register(mddev); | |
318 | + err = md_integrity_register(mddev); | |
319 | 319 | } |
320 | 320 | abort: |
321 | 321 | |
... | ... | @@ -489,7 +489,10 @@ |
489 | 489 | |
490 | 490 | mddev->queue->backing_dev_info.congested_fn = multipath_congested; |
491 | 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 | 496 | return 0; |
494 | 497 | |
495 | 498 | out_free_conf: |
drivers/md/raid0.c
drivers/md/raid1.c
... | ... | @@ -1132,7 +1132,7 @@ |
1132 | 1132 | p->rdev = rdev; |
1133 | 1133 | goto abort; |
1134 | 1134 | } |
1135 | - md_integrity_register(mddev); | |
1135 | + err = md_integrity_register(mddev); | |
1136 | 1136 | } |
1137 | 1137 | abort: |
1138 | 1138 | |
... | ... | @@ -2017,8 +2017,7 @@ |
2017 | 2017 | |
2018 | 2018 | mddev->queue->backing_dev_info.congested_fn = raid1_congested; |
2019 | 2019 | mddev->queue->backing_dev_info.congested_data = mddev; |
2020 | - md_integrity_register(mddev); | |
2021 | - return 0; | |
2020 | + return md_integrity_register(mddev); | |
2022 | 2021 | } |
2023 | 2022 | |
2024 | 2023 | static int stop(mddev_t *mddev) |
drivers/md/raid10.c
... | ... | @@ -1188,7 +1188,7 @@ |
1188 | 1188 | p->rdev = rdev; |
1189 | 1189 | goto abort; |
1190 | 1190 | } |
1191 | - md_integrity_register(mddev); | |
1191 | + err = md_integrity_register(mddev); | |
1192 | 1192 | } |
1193 | 1193 | abort: |
1194 | 1194 | |
... | ... | @@ -2343,7 +2343,10 @@ |
2343 | 2343 | |
2344 | 2344 | if (conf->near_copies < conf->raid_disks) |
2345 | 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 | 2350 | return 0; |
2348 | 2351 | |
2349 | 2352 | out_free_conf: |
fs/bio-integrity.c
fs/bio.c
... | ... | @@ -1636,9 +1636,6 @@ |
1636 | 1636 | if (!bs->bio_pool) |
1637 | 1637 | goto bad; |
1638 | 1638 | |
1639 | - if (bioset_integrity_create(bs, pool_size)) | |
1640 | - goto bad; | |
1641 | - | |
1642 | 1639 | if (!biovec_create_pools(bs, pool_size)) |
1643 | 1640 | return bs; |
1644 | 1641 | |
... | ... | @@ -1681,6 +1678,9 @@ |
1681 | 1678 | fs_bio_set = bioset_create(BIO_POOL_SIZE, 0); |
1682 | 1679 | if (!fs_bio_set) |
1683 | 1680 | panic("bio: can't allocate bios\n"); |
1681 | + | |
1682 | + if (bioset_integrity_create(fs_bio_set, BIO_POOL_SIZE)) | |
1683 | + panic("bio: can't create integrity pool\n"); | |
1684 | 1684 | |
1685 | 1685 | bio_split_pool = mempool_create_kmalloc_pool(BIO_SPLIT_ENTRIES, |
1686 | 1686 | sizeof(struct bio_pair)); |