]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
block: Require subsystems to explicitly allocate bio_set integrity mempool
authorMartin K. Petersen <martin.petersen@oracle.com>
Thu, 17 Mar 2011 10:11:05 +0000 (11:11 +0100)
committerJens Axboe <jaxboe@fusionio.com>
Thu, 17 Mar 2011 10:11:05 +0000 (11:11 +0100)
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>
drivers/md/dm-table.c
drivers/md/dm.c
drivers/md/dm.h
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
fs/bio-integrity.c
fs/bio.c

index f50a7b95225794272c81abdf2f66a396a7a69159..416d4e258df6df536d2cd7d38795e8e58b94efbc 100644 (file)
@@ -55,6 +55,7 @@ struct dm_table {
        struct dm_target *targets;
 
        unsigned discards_supported:1;
+       unsigned integrity_supported:1;
 
        /*
         * Indicates the rw permissions for the new logical
@@ -859,7 +860,7 @@ int dm_table_alloc_md_mempools(struct dm_table *t)
                return -EINVAL;
        }
 
-       t->mempools = dm_alloc_md_mempools(type);
+       t->mempools = dm_alloc_md_mempools(type, t->integrity_supported);
        if (!t->mempools)
                return -ENOMEM;
 
@@ -935,8 +936,10 @@ static int dm_table_prealloc_integrity(struct dm_table *t, struct mapped_device
        struct dm_dev_internal *dd;
 
        list_for_each_entry(dd, devices, list)
-               if (bdev_get_integrity(dd->dm_dev.bdev))
+               if (bdev_get_integrity(dd->dm_dev.bdev)) {
+                       t->integrity_supported = 1;
                        return blk_integrity_register(dm_disk(md), NULL);
+               }
 
        return 0;
 }
index d22b9905c1682e79e6f998dc6e638f9915d57355..88820704a1916e5db109b019643a55e3640a753f 100644 (file)
@@ -2620,9 +2620,10 @@ int dm_noflush_suspending(struct dm_target *ti)
 }
 EXPORT_SYMBOL_GPL(dm_noflush_suspending);
 
-struct dm_md_mempools *dm_alloc_md_mempools(unsigned type)
+struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity)
 {
        struct dm_md_mempools *pools = kmalloc(sizeof(*pools), GFP_KERNEL);
+       unsigned int pool_size = (type == DM_TYPE_BIO_BASED) ? 16 : MIN_IOS;
 
        if (!pools)
                return NULL;
@@ -2639,13 +2640,18 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type)
        if (!pools->tio_pool)
                goto free_io_pool_and_out;
 
-       pools->bs = (type == DM_TYPE_BIO_BASED) ?
-                   bioset_create(16, 0) : bioset_create(MIN_IOS, 0);
+       pools->bs = bioset_create(pool_size, 0);
        if (!pools->bs)
                goto free_tio_pool_and_out;
 
+       if (integrity && bioset_integrity_create(pools->bs, pool_size))
+               goto free_bioset_and_out;
+
        return pools;
 
+free_bioset_and_out:
+       bioset_free(pools->bs);
+
 free_tio_pool_and_out:
        mempool_destroy(pools->tio_pool);
 
index 0c2dd5f4af7658936a2c44bfa62a6aa774e56723..1aaf16746da86f6bfb9c9ffaab334841c044d92a 100644 (file)
@@ -149,7 +149,7 @@ void dm_kcopyd_exit(void);
 /*
  * Mempool operations
  */
-struct dm_md_mempools *dm_alloc_md_mempools(unsigned type);
+struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity);
 void dm_free_md_mempools(struct dm_md_mempools *pools);
 
 #endif
index 338804f8fb3b07e8628c23900013aed5eda6c565..abfb59a61ede75a25bc8f459456ed57eaf7acb71 100644 (file)
@@ -210,8 +210,7 @@ static int linear_run (mddev_t *mddev)
        blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
        mddev->queue->backing_dev_info.congested_fn = linear_congested;
        mddev->queue->backing_dev_info.congested_data = mddev;
-       md_integrity_register(mddev);
-       return 0;
+       return md_integrity_register(mddev);
 }
 
 static void free_conf(struct rcu_head *head)
index 86ba66c0b28a34080bc3c103e6f01d99c2c7c50a..1876761f1828f0081883693baaab9a0aac4c82ae 100644 (file)
@@ -1803,8 +1803,12 @@ int md_integrity_register(mddev_t *mddev)
                        mdname(mddev));
                return -EINVAL;
        }
-       printk(KERN_NOTICE "md: data integrity on %s enabled\n",
-               mdname(mddev));
+       printk(KERN_NOTICE "md: data integrity enabled on %s\n", mdname(mddev));
+       if (bioset_integrity_create(mddev->bio_set, BIO_POOL_SIZE)) {
+               printk(KERN_ERR "md: failed to create integrity pool for %s\n",
+                      mdname(mddev));
+               return -EINVAL;
+       }
        return 0;
 }
 EXPORT_SYMBOL(md_integrity_register);
index 5e694b151c308b3a06a4fcef15b971ad49ac98bd..c35890990985632646483a97e849277023850b1a 100644 (file)
@@ -315,7 +315,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
                        p->rdev = rdev;
                        goto abort;
                }
-               md_integrity_register(mddev);
+               err = md_integrity_register(mddev);
        }
 abort:
 
@@ -489,7 +489,10 @@ static int multipath_run (mddev_t *mddev)
 
        mddev->queue->backing_dev_info.congested_fn = multipath_congested;
        mddev->queue->backing_dev_info.congested_data = mddev;
-       md_integrity_register(mddev);
+
+       if (md_integrity_register(mddev))
+               goto out_free_conf;
+
        return 0;
 
 out_free_conf:
index 95916fd6394afcaa7563ead9b8c151d094eb53ba..e86bf3682e1e29c65b61f0ca7d3b00f94533046a 100644 (file)
@@ -379,8 +379,7 @@ static int raid0_run(mddev_t *mddev)
 
        blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec);
        dump_zones(mddev);
-       md_integrity_register(mddev);
-       return 0;
+       return md_integrity_register(mddev);
 }
 
 static int raid0_stop(mddev_t *mddev)
index 8f34ad5c478baa70446916724ea5d307a72b0aa4..c2a21ae56d977d6249f9c8501f124e50c48f15dd 100644 (file)
@@ -1132,7 +1132,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
                        p->rdev = rdev;
                        goto abort;
                }
-               md_integrity_register(mddev);
+               err = md_integrity_register(mddev);
        }
 abort:
 
@@ -2017,8 +2017,7 @@ static int run(mddev_t *mddev)
 
        mddev->queue->backing_dev_info.congested_fn = raid1_congested;
        mddev->queue->backing_dev_info.congested_data = mddev;
-       md_integrity_register(mddev);
-       return 0;
+       return md_integrity_register(mddev);
 }
 
 static int stop(mddev_t *mddev)
index c0d0f5f7e407fa1249f248c59078c8361d72ae0a..f7b62370b37446a96d5595e8f247b84b3689b145 100644 (file)
@@ -1188,7 +1188,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
                        p->rdev = rdev;
                        goto abort;
                }
-               md_integrity_register(mddev);
+               err = md_integrity_register(mddev);
        }
 abort:
 
@@ -2343,7 +2343,10 @@ static int run(mddev_t *mddev)
 
        if (conf->near_copies < conf->raid_disks)
                blk_queue_merge_bvec(mddev->queue, raid10_mergeable_bvec);
-       md_integrity_register(mddev);
+
+       if (md_integrity_register(mddev))
+               goto out_free_conf;
+
        return 0;
 
 out_free_conf:
index e49cce234c653162560796710ee125134053183d..9c5e6b2cd11a84fa3f04611b35cebb6e2232b186 100644 (file)
@@ -761,6 +761,9 @@ int bioset_integrity_create(struct bio_set *bs, int pool_size)
 {
        unsigned int max_slab = vecs_to_idx(BIO_MAX_PAGES);
 
+       if (bs->bio_integrity_pool)
+               return 0;
+
        bs->bio_integrity_pool =
                mempool_create_slab_pool(pool_size, bip_slab[max_slab].slab);
 
index 5694b756ed019a756c1f25a924fca58b94407b12..85e2eabb1f815e5e97f199f502b750cbe4c1d0af 100644 (file)
--- 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)
        if (!bs->bio_pool)
                goto bad;
 
-       if (bioset_integrity_create(bs, pool_size))
-               goto bad;
-
        if (!biovec_create_pools(bs, pool_size))
                return bs;
 
@@ -1682,6 +1679,9 @@ static int __init init_bio(void)
        if (!fs_bio_set)
                panic("bio: can't allocate bios\n");
 
+       if (bioset_integrity_create(fs_bio_set, BIO_POOL_SIZE))
+               panic("bio: can't create integrity pool\n");
+
        bio_split_pool = mempool_create_kmalloc_pool(BIO_SPLIT_ENTRIES,
                                                     sizeof(struct bio_pair));
        if (!bio_split_pool)