aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2016-07-19 05:28:42 -0400
committerJens Axboe <axboe@fb.com>2016-07-20 19:37:02 -0400
commited996a52c868b62c4e5bf529cb4ccb44bcfa2f8e (patch)
tree83c3fbdb4cd912fb925b5aee2ca45b8054a4aae3
parent70246286e94c335b5bea0cbc68a17a96dd620281 (diff)
block: simplify and cleanup bvec pool handling
Instead of a flag and an index just make sure an index of 0 means no need to free the bvec array. Also move the constants related to the bvec pools together and use a consistent naming scheme for them. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Reviewed-by: Mike Christie <mchristi@redhat.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--block/bio-integrity.c9
-rw-r--r--block/bio.c32
-rw-r--r--drivers/md/bcache/io.c1
-rw-r--r--include/linux/bio.h2
-rw-r--r--include/linux/blk_types.h22
5 files changed, 36 insertions, 30 deletions
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 711e4d8de6fa..11633fca27d3 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -53,7 +53,6 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
53{ 53{
54 struct bio_integrity_payload *bip; 54 struct bio_integrity_payload *bip;
55 struct bio_set *bs = bio->bi_pool; 55 struct bio_set *bs = bio->bi_pool;
56 unsigned long idx = BIO_POOL_NONE;
57 unsigned inline_vecs; 56 unsigned inline_vecs;
58 57
59 if (!bs || !bs->bio_integrity_pool) { 58 if (!bs || !bs->bio_integrity_pool) {
@@ -71,17 +70,19 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
71 memset(bip, 0, sizeof(*bip)); 70 memset(bip, 0, sizeof(*bip));
72 71
73 if (nr_vecs > inline_vecs) { 72 if (nr_vecs > inline_vecs) {
73 unsigned long idx = 0;
74
74 bip->bip_vec = bvec_alloc(gfp_mask, nr_vecs, &idx, 75 bip->bip_vec = bvec_alloc(gfp_mask, nr_vecs, &idx,
75 bs->bvec_integrity_pool); 76 bs->bvec_integrity_pool);
76 if (!bip->bip_vec) 77 if (!bip->bip_vec)
77 goto err; 78 goto err;
78 bip->bip_max_vcnt = bvec_nr_vecs(idx); 79 bip->bip_max_vcnt = bvec_nr_vecs(idx);
80 bip->bip_slab = idx;
79 } else { 81 } else {
80 bip->bip_vec = bip->bip_inline_vecs; 82 bip->bip_vec = bip->bip_inline_vecs;
81 bip->bip_max_vcnt = inline_vecs; 83 bip->bip_max_vcnt = inline_vecs;
82 } 84 }
83 85
84 bip->bip_slab = idx;
85 bip->bip_bio = bio; 86 bip->bip_bio = bio;
86 bio->bi_integrity = bip; 87 bio->bi_integrity = bip;
87 bio->bi_rw |= REQ_INTEGRITY; 88 bio->bi_rw |= REQ_INTEGRITY;
@@ -110,9 +111,7 @@ void bio_integrity_free(struct bio *bio)
110 bip->bip_vec->bv_offset); 111 bip->bip_vec->bv_offset);
111 112
112 if (bs && bs->bio_integrity_pool) { 113 if (bs && bs->bio_integrity_pool) {
113 if (bip->bip_slab != BIO_POOL_NONE) 114 bvec_free(bs->bvec_integrity_pool, bip->bip_vec, bip->bip_slab);
114 bvec_free(bs->bvec_integrity_pool, bip->bip_vec,
115 bip->bip_slab);
116 115
117 mempool_free(bip, bs->bio_integrity_pool); 116 mempool_free(bip, bs->bio_integrity_pool);
118 } else { 117 } else {
diff --git a/block/bio.c b/block/bio.c
index 848cd351513b..882b50ae3ad6 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -43,7 +43,7 @@
43 * unsigned short 43 * unsigned short
44 */ 44 */
45#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) } 45#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) }
46static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = { 46static struct biovec_slab bvec_slabs[BVEC_POOL_NR] __read_mostly = {
47 BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES), 47 BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
48}; 48};
49#undef BV 49#undef BV
@@ -160,11 +160,15 @@ unsigned int bvec_nr_vecs(unsigned short idx)
160 160
161void bvec_free(mempool_t *pool, struct bio_vec *bv, unsigned int idx) 161void bvec_free(mempool_t *pool, struct bio_vec *bv, unsigned int idx)
162{ 162{
163 BIO_BUG_ON(idx >= BIOVEC_NR_POOLS); 163 if (!idx)
164 return;
165 idx--;
166
167 BIO_BUG_ON(idx >= BVEC_POOL_NR);
164 168
165 if (idx == BIOVEC_MAX_IDX) 169 if (idx == BVEC_POOL_MAX) {
166 mempool_free(bv, pool); 170 mempool_free(bv, pool);
167 else { 171 } else {
168 struct biovec_slab *bvs = bvec_slabs + idx; 172 struct biovec_slab *bvs = bvec_slabs + idx;
169 173
170 kmem_cache_free(bvs->slab, bv); 174 kmem_cache_free(bvs->slab, bv);
@@ -206,7 +210,7 @@ struct bio_vec *bvec_alloc(gfp_t gfp_mask, int nr, unsigned long *idx,
206 * idx now points to the pool we want to allocate from. only the 210 * idx now points to the pool we want to allocate from. only the
207 * 1-vec entry pool is mempool backed. 211 * 1-vec entry pool is mempool backed.
208 */ 212 */
209 if (*idx == BIOVEC_MAX_IDX) { 213 if (*idx == BVEC_POOL_MAX) {
210fallback: 214fallback:
211 bvl = mempool_alloc(pool, gfp_mask); 215 bvl = mempool_alloc(pool, gfp_mask);
212 } else { 216 } else {
@@ -226,11 +230,12 @@ fallback:
226 */ 230 */
227 bvl = kmem_cache_alloc(bvs->slab, __gfp_mask); 231 bvl = kmem_cache_alloc(bvs->slab, __gfp_mask);
228 if (unlikely(!bvl && (gfp_mask & __GFP_DIRECT_RECLAIM))) { 232 if (unlikely(!bvl && (gfp_mask & __GFP_DIRECT_RECLAIM))) {
229 *idx = BIOVEC_MAX_IDX; 233 *idx = BVEC_POOL_MAX;
230 goto fallback; 234 goto fallback;
231 } 235 }
232 } 236 }
233 237
238 (*idx)++;
234 return bvl; 239 return bvl;
235} 240}
236 241
@@ -250,8 +255,7 @@ static void bio_free(struct bio *bio)
250 __bio_free(bio); 255 __bio_free(bio);
251 256
252 if (bs) { 257 if (bs) {
253 if (bio_flagged(bio, BIO_OWNS_VEC)) 258 bvec_free(bs->bvec_pool, bio->bi_io_vec, BVEC_POOL_IDX(bio));
254 bvec_free(bs->bvec_pool, bio->bi_io_vec, BIO_POOL_IDX(bio));
255 259
256 /* 260 /*
257 * If we have front padding, adjust the bio pointer before freeing 261 * If we have front padding, adjust the bio pointer before freeing
@@ -420,7 +424,6 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
420 gfp_t saved_gfp = gfp_mask; 424 gfp_t saved_gfp = gfp_mask;
421 unsigned front_pad; 425 unsigned front_pad;
422 unsigned inline_vecs; 426 unsigned inline_vecs;
423 unsigned long idx = BIO_POOL_NONE;
424 struct bio_vec *bvl = NULL; 427 struct bio_vec *bvl = NULL;
425 struct bio *bio; 428 struct bio *bio;
426 void *p; 429 void *p;
@@ -480,6 +483,8 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
480 bio_init(bio); 483 bio_init(bio);
481 484
482 if (nr_iovecs > inline_vecs) { 485 if (nr_iovecs > inline_vecs) {
486 unsigned long idx = 0;
487
483 bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx, bs->bvec_pool); 488 bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx, bs->bvec_pool);
484 if (!bvl && gfp_mask != saved_gfp) { 489 if (!bvl && gfp_mask != saved_gfp) {
485 punt_bios_to_rescuer(bs); 490 punt_bios_to_rescuer(bs);
@@ -490,13 +495,12 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
490 if (unlikely(!bvl)) 495 if (unlikely(!bvl))
491 goto err_free; 496 goto err_free;
492 497
493 bio_set_flag(bio, BIO_OWNS_VEC); 498 bio->bi_flags |= idx << BVEC_POOL_OFFSET;
494 } else if (nr_iovecs) { 499 } else if (nr_iovecs) {
495 bvl = bio->bi_inline_vecs; 500 bvl = bio->bi_inline_vecs;
496 } 501 }
497 502
498 bio->bi_pool = bs; 503 bio->bi_pool = bs;
499 bio->bi_flags |= idx << BIO_POOL_OFFSET;
500 bio->bi_max_vecs = nr_iovecs; 504 bio->bi_max_vecs = nr_iovecs;
501 bio->bi_io_vec = bvl; 505 bio->bi_io_vec = bvl;
502 return bio; 506 return bio;
@@ -568,7 +572,7 @@ EXPORT_SYMBOL(bio_phys_segments);
568 */ 572 */
569void __bio_clone_fast(struct bio *bio, struct bio *bio_src) 573void __bio_clone_fast(struct bio *bio, struct bio *bio_src)
570{ 574{
571 BUG_ON(bio->bi_pool && BIO_POOL_IDX(bio) != BIO_POOL_NONE); 575 BUG_ON(bio->bi_pool && BVEC_POOL_IDX(bio));
572 576
573 /* 577 /*
574 * most users will be overriding ->bi_bdev with a new target, 578 * most users will be overriding ->bi_bdev with a new target,
@@ -1832,7 +1836,7 @@ EXPORT_SYMBOL_GPL(bio_trim);
1832 */ 1836 */
1833mempool_t *biovec_create_pool(int pool_entries) 1837mempool_t *biovec_create_pool(int pool_entries)
1834{ 1838{
1835 struct biovec_slab *bp = bvec_slabs + BIOVEC_MAX_IDX; 1839 struct biovec_slab *bp = bvec_slabs + BVEC_POOL_MAX;
1836 1840
1837 return mempool_create_slab_pool(pool_entries, bp->slab); 1841 return mempool_create_slab_pool(pool_entries, bp->slab);
1838} 1842}
@@ -2009,7 +2013,7 @@ static void __init biovec_init_slabs(void)
2009{ 2013{
2010 int i; 2014 int i;
2011 2015
2012 for (i = 0; i < BIOVEC_NR_POOLS; i++) { 2016 for (i = 0; i < BVEC_POOL_NR; i++) {
2013 int size; 2017 int size;
2014 struct biovec_slab *bvs = bvec_slabs + i; 2018 struct biovec_slab *bvs = bvec_slabs + i;
2015 2019
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c
index fd885cc2afad..e97b0acf7b8d 100644
--- a/drivers/md/bcache/io.c
+++ b/drivers/md/bcache/io.c
@@ -25,7 +25,6 @@ struct bio *bch_bbio_alloc(struct cache_set *c)
25 struct bio *bio = &b->bio; 25 struct bio *bio = &b->bio;
26 26
27 bio_init(bio); 27 bio_init(bio);
28 bio->bi_flags |= BIO_POOL_NONE << BIO_POOL_OFFSET;
29 bio->bi_max_vecs = bucket_pages(c); 28 bio->bi_max_vecs = bucket_pages(c);
30 bio->bi_io_vec = bio->bi_inline_vecs; 29 bio->bi_io_vec = bio->bi_inline_vecs;
31 30
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 0bbb2e332410..141cfa95a185 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -715,8 +715,6 @@ static inline void bio_inc_remaining(struct bio *bio)
715 * and the bvec_slabs[]. 715 * and the bvec_slabs[].
716 */ 716 */
717#define BIO_POOL_SIZE 2 717#define BIO_POOL_SIZE 2
718#define BIOVEC_NR_POOLS 6
719#define BIOVEC_MAX_IDX (BIOVEC_NR_POOLS - 1)
720 718
721struct bio_set { 719struct bio_set {
722 struct kmem_cache *bio_slab; 720 struct kmem_cache *bio_slab;
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index efba1f2ace2e..b76463ea3587 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -134,19 +134,25 @@ struct bio {
134 134
135/* 135/*
136 * Flags starting here get preserved by bio_reset() - this includes 136 * Flags starting here get preserved by bio_reset() - this includes
137 * BIO_POOL_IDX() 137 * BVEC_POOL_IDX()
138 */ 138 */
139#define BIO_RESET_BITS 13 139#define BIO_RESET_BITS 13
140#define BIO_OWNS_VEC 13 /* bio_free() should free bvec */
141 140
142/* 141/*
143 * top 4 bits of bio flags indicate the pool this bio came from 142 * We support 6 different bvec pools, the last one is magic in that it
143 * is backed by a mempool.
144 */ 144 */
145#define BIO_POOL_BITS (4) 145#define BVEC_POOL_NR 6
146#define BIO_POOL_NONE ((1UL << BIO_POOL_BITS) - 1) 146#define BVEC_POOL_MAX (BVEC_POOL_NR - 1)
147#define BIO_POOL_OFFSET (32 - BIO_POOL_BITS) 147
148#define BIO_POOL_MASK (1UL << BIO_POOL_OFFSET) 148/*
149#define BIO_POOL_IDX(bio) ((bio)->bi_flags >> BIO_POOL_OFFSET) 149 * Top 4 bits of bio flags indicate the pool the bvecs came from. We add
150 * 1 to the actual index so that 0 indicates that there are no bvecs to be
151 * freed.
152 */
153#define BVEC_POOL_BITS (4)
154#define BVEC_POOL_OFFSET (32 - BVEC_POOL_BITS)
155#define BVEC_POOL_IDX(bio) ((bio)->bi_flags >> BVEC_POOL_OFFSET)
150 156
151#endif /* CONFIG_BLOCK */ 157#endif /* CONFIG_BLOCK */
152 158