diff options
| -rw-r--r-- | drivers/md/dm-crypt.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-io.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm.c | 2 | ||||
| -rw-r--r-- | fs/bio-integrity.c | 2 | ||||
| -rw-r--r-- | fs/bio.c | 191 | ||||
| -rw-r--r-- | include/linux/bio.h | 6 |
6 files changed, 170 insertions, 35 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index ce26c84af064..3326750ec02c 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
| @@ -1060,7 +1060,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 1060 | goto bad_page_pool; | 1060 | goto bad_page_pool; |
| 1061 | } | 1061 | } |
| 1062 | 1062 | ||
| 1063 | cc->bs = bioset_create(MIN_IOS, MIN_IOS); | 1063 | cc->bs = bioset_create(MIN_IOS, 0); |
| 1064 | if (!cc->bs) { | 1064 | if (!cc->bs) { |
| 1065 | ti->error = "Cannot allocate crypt bioset"; | 1065 | ti->error = "Cannot allocate crypt bioset"; |
| 1066 | goto bad_bs; | 1066 | goto bad_bs; |
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 2fd6d4450637..a34338567a2a 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
| @@ -56,7 +56,7 @@ struct dm_io_client *dm_io_client_create(unsigned num_pages) | |||
| 56 | if (!client->pool) | 56 | if (!client->pool) |
| 57 | goto bad; | 57 | goto bad; |
| 58 | 58 | ||
| 59 | client->bios = bioset_create(16, 16); | 59 | client->bios = bioset_create(16, 0); |
| 60 | if (!client->bios) | 60 | if (!client->bios) |
| 61 | goto bad; | 61 | goto bad; |
| 62 | 62 | ||
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 343094c3feeb..421c9f02d8ca 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -1093,7 +1093,7 @@ static struct mapped_device *alloc_dev(int minor) | |||
| 1093 | if (!md->tio_pool) | 1093 | if (!md->tio_pool) |
| 1094 | goto bad_tio_pool; | 1094 | goto bad_tio_pool; |
| 1095 | 1095 | ||
| 1096 | md->bs = bioset_create(16, 16); | 1096 | md->bs = bioset_create(16, 0); |
| 1097 | if (!md->bs) | 1097 | if (!md->bs) |
| 1098 | goto bad_no_bioset; | 1098 | goto bad_no_bioset; |
| 1099 | 1099 | ||
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c index 19caf7c962ac..77ebc3c263d6 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c | |||
| @@ -111,7 +111,7 @@ void bio_integrity_free(struct bio *bio, struct bio_set *bs) | |||
| 111 | && bip->bip_buf != NULL) | 111 | && bip->bip_buf != NULL) |
| 112 | kfree(bip->bip_buf); | 112 | kfree(bip->bip_buf); |
| 113 | 113 | ||
| 114 | mempool_free(bip->bip_vec, bs->bvec_pools[bip->bip_pool]); | 114 | bvec_free_bs(bs, bip->bip_vec, bip->bip_pool); |
| 115 | mempool_free(bip, bs->bio_integrity_pool); | 115 | mempool_free(bip, bs->bio_integrity_pool); |
| 116 | 116 | ||
| 117 | bio->bi_integrity = NULL; | 117 | bio->bi_integrity = NULL; |
| @@ -31,8 +31,6 @@ | |||
| 31 | 31 | ||
| 32 | DEFINE_TRACE(block_split); | 32 | DEFINE_TRACE(block_split); |
| 33 | 33 | ||
| 34 | static struct kmem_cache *bio_slab __read_mostly; | ||
| 35 | |||
| 36 | static mempool_t *bio_split_pool __read_mostly; | 34 | static mempool_t *bio_split_pool __read_mostly; |
| 37 | 35 | ||
| 38 | /* | 36 | /* |
| @@ -40,9 +38,8 @@ static mempool_t *bio_split_pool __read_mostly; | |||
| 40 | * break badly! cannot be bigger than what you can fit into an | 38 | * break badly! cannot be bigger than what you can fit into an |
| 41 | * unsigned short | 39 | * unsigned short |
| 42 | */ | 40 | */ |
| 43 | |||
| 44 | #define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) } | 41 | #define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) } |
| 45 | static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = { | 42 | struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = { |
| 46 | BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES), | 43 | BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES), |
| 47 | }; | 44 | }; |
| 48 | #undef BV | 45 | #undef BV |
| @@ -53,11 +50,119 @@ static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = { | |||
| 53 | */ | 50 | */ |
| 54 | struct bio_set *fs_bio_set; | 51 | struct bio_set *fs_bio_set; |
| 55 | 52 | ||
| 53 | /* | ||
| 54 | * Our slab pool management | ||
| 55 | */ | ||
| 56 | struct bio_slab { | ||
| 57 | struct kmem_cache *slab; | ||
| 58 | unsigned int slab_ref; | ||
| 59 | unsigned int slab_size; | ||
| 60 | char name[8]; | ||
| 61 | }; | ||
| 62 | static DEFINE_MUTEX(bio_slab_lock); | ||
| 63 | static struct bio_slab *bio_slabs; | ||
| 64 | static unsigned int bio_slab_nr, bio_slab_max; | ||
| 65 | |||
| 66 | static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size) | ||
| 67 | { | ||
| 68 | unsigned int sz = sizeof(struct bio) + extra_size; | ||
| 69 | struct kmem_cache *slab = NULL; | ||
| 70 | struct bio_slab *bslab; | ||
| 71 | unsigned int i, entry = -1; | ||
| 72 | |||
| 73 | mutex_lock(&bio_slab_lock); | ||
| 74 | |||
| 75 | i = 0; | ||
| 76 | while (i < bio_slab_nr) { | ||
| 77 | struct bio_slab *bslab = &bio_slabs[i]; | ||
| 78 | |||
| 79 | if (!bslab->slab && entry == -1) | ||
| 80 | entry = i; | ||
| 81 | else if (bslab->slab_size == sz) { | ||
| 82 | slab = bslab->slab; | ||
| 83 | bslab->slab_ref++; | ||
| 84 | break; | ||
| 85 | } | ||
| 86 | i++; | ||
| 87 | } | ||
| 88 | |||
| 89 | if (slab) | ||
| 90 | goto out_unlock; | ||
| 91 | |||
| 92 | if (bio_slab_nr == bio_slab_max && entry == -1) { | ||
| 93 | bio_slab_max <<= 1; | ||
| 94 | bio_slabs = krealloc(bio_slabs, | ||
| 95 | bio_slab_max * sizeof(struct bio_slab), | ||
| 96 | GFP_KERNEL); | ||
| 97 | if (!bio_slabs) | ||
| 98 | goto out_unlock; | ||
| 99 | } | ||
| 100 | if (entry == -1) | ||
| 101 | entry = bio_slab_nr++; | ||
| 102 | |||
| 103 | bslab = &bio_slabs[entry]; | ||
| 104 | |||
| 105 | snprintf(bslab->name, sizeof(bslab->name), "bio-%d", entry); | ||
| 106 | slab = kmem_cache_create(bslab->name, sz, 0, SLAB_HWCACHE_ALIGN, NULL); | ||
| 107 | if (!slab) | ||
| 108 | goto out_unlock; | ||
| 109 | |||
| 110 | printk("bio: create slab <%s> at %d\n", bslab->name, entry); | ||
| 111 | bslab->slab = slab; | ||
| 112 | bslab->slab_ref = 1; | ||
| 113 | bslab->slab_size = sz; | ||
| 114 | out_unlock: | ||
| 115 | mutex_unlock(&bio_slab_lock); | ||
| 116 | return slab; | ||
| 117 | } | ||
| 118 | |||
| 119 | static void bio_put_slab(struct bio_set *bs) | ||
| 120 | { | ||
| 121 | struct bio_slab *bslab = NULL; | ||
| 122 | unsigned int i; | ||
| 123 | |||
| 124 | mutex_lock(&bio_slab_lock); | ||
| 125 | |||
| 126 | for (i = 0; i < bio_slab_nr; i++) { | ||
| 127 | if (bs->bio_slab == bio_slabs[i].slab) { | ||
| 128 | bslab = &bio_slabs[i]; | ||
| 129 | break; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | if (WARN(!bslab, KERN_ERR "bio: unable to find slab!\n")) | ||
| 134 | goto out; | ||
| 135 | |||
| 136 | WARN_ON(!bslab->slab_ref); | ||
| 137 | |||
| 138 | if (--bslab->slab_ref) | ||
| 139 | goto out; | ||
| 140 | |||
| 141 | kmem_cache_destroy(bslab->slab); | ||
| 142 | bslab->slab = NULL; | ||
| 143 | |||
| 144 | out: | ||
| 145 | mutex_unlock(&bio_slab_lock); | ||
| 146 | } | ||
| 147 | |||
| 56 | unsigned int bvec_nr_vecs(unsigned short idx) | 148 | unsigned int bvec_nr_vecs(unsigned short idx) |
| 57 | { | 149 | { |
| 58 | return bvec_slabs[idx].nr_vecs; | 150 | return bvec_slabs[idx].nr_vecs; |
| 59 | } | 151 | } |
| 60 | 152 | ||
| 153 | void bvec_free_bs(struct bio_set *bs, struct bio_vec *bv, unsigned int idx) | ||
| 154 | { | ||
| 155 | BIO_BUG_ON(idx >= BIOVEC_NR_POOLS); | ||
| 156 | |||
| 157 | if (idx == BIOVEC_MAX_IDX) | ||
| 158 | mempool_free(bv, bs->bvec_pool); | ||
| 159 | else { | ||
| 160 | struct biovec_slab *bvs = bvec_slabs + idx; | ||
| 161 | |||
| 162 | kmem_cache_free(bvs->slab, bv); | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 61 | struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, | 166 | struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, |
| 62 | struct bio_set *bs) | 167 | struct bio_set *bs) |
| 63 | { | 168 | { |
| @@ -134,24 +239,22 @@ fallback: | |||
| 134 | 239 | ||
| 135 | void bio_free(struct bio *bio, struct bio_set *bs) | 240 | void bio_free(struct bio *bio, struct bio_set *bs) |
| 136 | { | 241 | { |
| 137 | if (bio->bi_io_vec) { | 242 | |
