diff options
author | Christoph Hellwig <hch@lst.de> | 2016-07-19 05:28:42 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2016-07-20 19:37:02 -0400 |
commit | ed996a52c868b62c4e5bf529cb4ccb44bcfa2f8e (patch) | |
tree | 83c3fbdb4cd912fb925b5aee2ca45b8054a4aae3 | |
parent | 70246286e94c335b5bea0cbc68a17a96dd620281 (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.c | 9 | ||||
-rw-r--r-- | block/bio.c | 32 | ||||
-rw-r--r-- | drivers/md/bcache/io.c | 1 | ||||
-rw-r--r-- | include/linux/bio.h | 2 | ||||
-rw-r--r-- | include/linux/blk_types.h | 22 |
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) } |
46 | static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = { | 46 | static 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 | ||
161 | void bvec_free(mempool_t *pool, struct bio_vec *bv, unsigned int idx) | 161 | void 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) { |
210 | fallback: | 214 | fallback: |
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 | */ |
569 | void __bio_clone_fast(struct bio *bio, struct bio *bio_src) | 573 | void __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 | */ |
1833 | mempool_t *biovec_create_pool(int pool_entries) | 1837 | mempool_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 | ||
721 | struct bio_set { | 719 | struct 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 | ||