--- 2.6.23.12.base/drivers/md/dm.c 2008-02-14 02:01:41.000000000 -0800 +++ 2.6.23.12/drivers/md/dm.c 2008-03-11 01:39:04.000000000 -0700 @@ -1017,7 +1017,7 @@ static struct mapped_device *alloc_dev(i if (!md->tio_pool) goto bad3; - md->bs = bioset_create(16, 16); + md->bs = bioset_create(16); if (!md->bs) goto bad_no_bioset; --- 2.6.23.12.base/drivers/md/dm-crypt.c 2008-01-28 20:33:06.000000000 -0800 +++ 2.6.23.12/drivers/md/dm-crypt.c 2008-03-11 01:47:19.000000000 -0700 @@ -854,7 +854,7 @@ static int crypt_ctr(struct dm_target *t goto bad4; } - cc->bs = bioset_create(MIN_IOS, MIN_IOS); + cc->bs = bioset_create(MIN_IOS); if (!cc->bs) { ti->error = "Cannot allocate crypt bioset"; goto bad_bs; --- 2.6.23.12.base/drivers/md/dm-io.c 2008-01-28 20:33:06.000000000 -0800 +++ 2.6.23.12/drivers/md/dm-io.c 2008-03-11 01:39:04.000000000 -0700 @@ -55,7 +55,7 @@ struct dm_io_client *dm_io_client_create if (!client->pool) goto bad; - client->bios = bioset_create(16, 16); + client->bios = bioset_create(16); if (!client->bios) goto bad; --- 2.6.23.12.base/fs/bio.c 2008-01-28 20:33:09.000000000 -0800 +++ 2.6.23.12/fs/bio.c 2008-03-11 01:39:04.000000000 -0700 @@ -29,10 +29,7 @@ #include /* for struct sg_iovec */ #define BIO_POOL_SIZE 2 - -static struct kmem_cache *bio_slab __read_mostly; - -#define BIOVEC_NR_POOLS 6 +#define BIO_NR_POOLS 6 /* * a small number of entries is fine, not going to be performance critical. @@ -41,7 +38,7 @@ static struct kmem_cache *bio_slab __rea #define BIO_SPLIT_ENTRIES 2 mempool_t *bio_split_pool __read_mostly; -struct biovec_slab { +struct bio_slab { int nr_vecs; char *name; struct kmem_cache *slab; @@ -53,68 +50,34 @@ struct biovec_slab { * unsigned short */ -#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) } -static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = { +#define BV(x) { .nr_vecs = x, .name = "bio-"__stringify(x) } +static struct bio_slab bio_slabs[BIO_NR_POOLS] __read_mostly = { BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES), }; #undef BV /* * bio_set is used to allow other portions of the IO system to - * allocate their own private memory pools for bio and iovec structures. - * These memory pools in turn all allocate from the bio_slab - * and the bvec_slabs[]. + * allocate their own private memory pools for bio structures. + * These memory pools in turn all allocate from the bio_slabs[]. */ struct bio_set { - mempool_t *bio_pool; - mempool_t *bvec_pools[BIOVEC_NR_POOLS]; + mempool_t *bio_pools[BIO_NR_POOLS]; }; /* - * fs_bio_set is the bio_set containing bio and iovec memory pools used by + * fs_bio_set is the bio_set containing bio memory pools used by * IO code that does not need private memory pools. */ static struct bio_set *fs_bio_set; -static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs) -{ - struct bio_vec *bvl; - - /* - * see comment near bvec_array define! - */ - switch (nr) { - case 1 : *idx = 0; break; - case 2 ... 4: *idx = 1; break; - case 5 ... 16: *idx = 2; break; - case 17 ... 64: *idx = 3; break; - case 65 ... 128: *idx = 4; break; - case 129 ... BIO_MAX_PAGES: *idx = 5; break; - default: - return NULL; - } - /* - * idx now points to the pool we want to allocate from - */ - - bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask); - if (bvl) { - struct biovec_slab *bp = bvec_slabs + *idx; - - memset(bvl, 0, bp->nr_vecs * sizeof(struct bio_vec)); - } - - return bvl; -} - void bio_free(struct bio *bio, struct bio_set *bio_set) { const int pool_idx = BIO_POOL_IDX(bio); - BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS); + BIO_BUG_ON(pool_idx >= BIO_NR_POOLS); - mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]); - mempool_free(bio, bio_set->bio_pool); + mempool_free(bio, bio_set->bio_pools[pool_idx]); } /* @@ -127,21 +90,7 @@ static void bio_fs_destructor(struct bio void bio_init(struct bio *bio) { - bio->bi_next = NULL; - bio->bi_bdev = NULL; - bio->bi_flags = 1 << BIO_UPTODATE; - bio->bi_rw = 0; - bio->bi_vcnt = 0; - bio->bi_idx = 0; - bio->bi_phys_segments = 0; - bio->bi_hw_segments = 0; - bio->bi_hw_front_size = 0; - bio->bi_hw_back_size = 0; - bio->bi_size = 0; - bio->bi_max_vecs = 0; - bio->bi_end_io = NULL; - atomic_set(&bio->bi_cnt, 1); - bio->bi_private = NULL; + *bio = (struct bio){ .bi_flags = 1 << BIO_UPTODATE, .bi_cnt = ATOMIC_INIT(1) }; } /** @@ -160,27 +109,28 @@ void bio_init(struct bio *bio) **/ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) { - struct bio *bio = mempool_alloc(bs->bio_pool, gfp_mask); - - if (likely(bio)) { - struct bio_vec *bvl = NULL; - - bio_init(bio); - if (likely(nr_iovecs)) { - unsigned long idx = 0; /* shut up gcc */ - - bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs); - if (unlikely(!bvl)) { - mempool_free(bio, bs->bio_pool); - bio = NULL; - goto out; - } - bio->bi_flags |= idx << BIO_POOL_OFFSET; - bio->bi_max_vecs = bvec_slabs[idx].nr_vecs; - } - bio->bi_io_vec = bvl; + struct bio *bio; + unsigned idx; + /* + * see comment near bvec_array define! + */ + switch (nr_iovecs) { + case 0 ... 1: idx = 0; break; + case 2 ... 4: idx = 1; break; + case 5 ... 16: idx = 2; break; + case 17 ... 64: idx = 3; break; + case 65 ... 128: idx = 4; break; + case 129 ... BIO_MAX_PAGES: idx = 5; break; + default: + return NULL; } -out: + if (!(bio = mempool_alloc(bs->bio_pools[idx], gfp_mask|__GFP_ZERO))) + return NULL; + + bio_init(bio); + bio->bi_flags |= idx << BIO_POOL_OFFSET; + bio->bi_max_vecs = bio_slabs[idx].nr_vecs; + bio->bi_io_vec = (void *)bio + sizeof(struct bio); return bio; } @@ -1117,87 +1067,54 @@ struct bio_pair *bio_split(struct bio *b /* - * create memory pools for biovec's in a bio_set. - * use the global biovec slabs created for general use. + * create memory pools for bios in a bio_set. + * use the global bio slabs created for general use. */ -static int biovec_create_pools(struct bio_set *bs, int pool_entries) -{ - int i; - - for (i = 0; i < BIOVEC_NR_POOLS; i++) { - struct biovec_slab *bp = bvec_slabs + i; - mempool_t **bvp = bs->bvec_pools + i; - - *bvp = mempool_create_slab_pool(pool_entries, bp->slab); - if (!*bvp) - return -ENOMEM; - } - return 0; -} - -static void biovec_free_pools(struct bio_set *bs) +void bioset_free(struct bio_set *bs) { int i; - for (i = 0; i < BIOVEC_NR_POOLS; i++) { - mempool_t *bvp = bs->bvec_pools[i]; + for (i = 0; i < BIO_NR_POOLS; i++) { + mempool_t *bvp = bs->bio_pools[i]; if (bvp) mempool_destroy(bvp); } - -} - -void bioset_free(struct bio_set *bs) -{ - if (bs->bio_pool) - mempool_destroy(bs->bio_pool); - - biovec_free_pools(bs); - kfree(bs); } -struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size) +struct bio_set *bioset_create(int entries) { struct bio_set *bs = kzalloc(sizeof(*bs), GFP_KERNEL); + int i; if (!bs) return NULL; - bs->bio_pool = mempool_create_slab_pool(bio_pool_size, bio_slab); - if (!bs->bio_pool) - goto bad; - - if (!biovec_create_pools(bs, bvec_pool_size)) - return bs; - -bad: - bioset_free(bs); - return NULL; + for (i = 0; i < BIO_NR_POOLS; i++) { + mempool_t *p = mempool_create_slab_pool(entries, bio_slabs[i].slab); + if (!(bs->bio_pools[i] = p)) { + bioset_free(bs); + return NULL; + } + } + return bs; } -static void __init biovec_init_slabs(void) +static int __init init_bio(void) { int i; - for (i = 0; i < BIOVEC_NR_POOLS; i++) { + for (i = 0; i < BIO_NR_POOLS; i++) { int size; - struct biovec_slab *bvs = bvec_slabs + i; + struct bio_slab *bvs = bio_slabs + i; - size = bvs->nr_vecs * sizeof(struct bio_vec); + size = bvs->nr_vecs * sizeof(struct bio_vec) + sizeof(struct bio); bvs->slab = kmem_cache_create(bvs->name, size, 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); } -} - -static int __init init_bio(void) -{ - bio_slab = KMEM_CACHE(bio, SLAB_HWCACHE_ALIGN|SLAB_PANIC); - - biovec_init_slabs(); - fs_bio_set = bioset_create(BIO_POOL_SIZE, 2); + fs_bio_set = bioset_create(BIO_POOL_SIZE); if (!fs_bio_set) panic("bio: can't allocate bios\n"); --- 2.6.23.12.base/include/linux/bio.h 2008-01-28 20:33:09.000000000 -0800 +++ 2.6.23.12/include/linux/bio.h 2008-03-11 01:39:42.000000000 -0700 @@ -278,7 +278,7 @@ extern struct bio_pair *bio_split(struct extern mempool_t *bio_split_pool; extern void bio_pair_release(struct bio_pair *dbio); -extern struct bio_set *bioset_create(int, int); +extern struct bio_set *bioset_create(int); extern void bioset_free(struct bio_set *); extern struct bio *bio_alloc(gfp_t, int);