diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-05-08 21:33:50 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-05-14 15:16:03 -0400 |
commit | 8aa6ba2f6e3deaff70e517e3cfbf38d1105f9d4f (patch) | |
tree | a2b42e3b8fb2f7671a08c6e0a63d1dd6752f1765 | |
parent | c1a67fefd0546a5552289c65fe31b1d60e64b643 (diff) |
block: Convert bio_set to mempool_init()
Minor performance improvement by getting rid of pointer indirections
from allocation/freeing fastpaths.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | block/bio-integrity.c | 29 | ||||
-rw-r--r-- | block/bio.c | 36 | ||||
-rw-r--r-- | include/linux/bio.h | 10 |
3 files changed, 36 insertions, 39 deletions
diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 9cfdd6c83b5b..add7c7c85335 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c | |||
@@ -56,12 +56,12 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, | |||
56 | struct bio_set *bs = bio->bi_pool; | 56 | struct bio_set *bs = bio->bi_pool; |
57 | unsigned inline_vecs; | 57 | unsigned inline_vecs; |
58 | 58 | ||
59 | if (!bs || !bs->bio_integrity_pool) { | 59 | if (!bs || !mempool_initialized(&bs->bio_integrity_pool)) { |
60 | bip = kmalloc(sizeof(struct bio_integrity_payload) + | 60 | bip = kmalloc(sizeof(struct bio_integrity_payload) + |
61 | sizeof(struct bio_vec) * nr_vecs, gfp_mask); | 61 | sizeof(struct bio_vec) * nr_vecs, gfp_mask); |
62 | inline_vecs = nr_vecs; | 62 | inline_vecs = nr_vecs; |
63 | } else { | 63 | } else { |
64 | bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask); | 64 | bip = mempool_alloc(&bs->bio_integrity_pool, gfp_mask); |
65 | inline_vecs = BIP_INLINE_VECS; | 65 | inline_vecs = BIP_INLINE_VECS; |
66 | } | 66 | } |
67 | 67 | ||
@@ -74,7 +74,7 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, | |||
74 | unsigned long idx = 0; | 74 | unsigned long idx = 0; |
75 | 75 | ||
76 | bip->bip_vec = bvec_alloc(gfp_mask, nr_vecs, &idx, | 76 | bip->bip_vec = bvec_alloc(gfp_mask, nr_vecs, &idx, |
77 | bs->bvec_integrity_pool); | 77 | &bs->bvec_integrity_pool); |
78 | if (!bip->bip_vec) | 78 | if (!bip->bip_vec) |
79 | goto err; | 79 | goto err; |
80 | bip->bip_max_vcnt = bvec_nr_vecs(idx); | 80 | bip->bip_max_vcnt = bvec_nr_vecs(idx); |
@@ -90,7 +90,7 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, | |||
90 | 90 | ||
91 | return bip; | 91 | return bip; |
92 | err: | 92 | err: |
93 | mempool_free(bip, bs->bio_integrity_pool); | 93 | mempool_free(bip, &bs->bio_integrity_pool); |
94 | return ERR_PTR(-ENOMEM); | 94 | return ERR_PTR(-ENOMEM); |
95 | } | 95 | } |
96 | EXPORT_SYMBOL(bio_integrity_alloc); | 96 | EXPORT_SYMBOL(bio_integrity_alloc); |
@@ -111,10 +111,10 @@ static void bio_integrity_free(struct bio *bio) | |||
111 | kfree(page_address(bip->bip_vec->bv_page) + | 111 | kfree(page_address(bip->bip_vec->bv_page) + |
112 | bip->bip_vec->bv_offset); | 112 | bip->bip_vec->bv_offset); |
113 | 113 | ||
114 | if (bs && bs->bio_integrity_pool) { | 114 | if (bs && mempool_initialized(&bs->bio_integrity_pool)) { |
115 | bvec_free(bs->bvec_integrity_pool, bip->bip_vec, bip->bip_slab); | 115 | bvec_free(&bs->bvec_integrity_pool, bip->bip_vec, bip->bip_slab); |
116 | 116 | ||
117 | mempool_free(bip, bs->bio_integrity_pool); | 117 | mempool_free(bip, &bs->bio_integrity_pool); |
118 | } else { | 118 | } else { |
119 | kfree(bip); | 119 | kfree(bip); |
120 | } | 120 | } |
@@ -465,16 +465,15 @@ EXPORT_SYMBOL(bio_integrity_clone); | |||
465 | 465 | ||
466 | int bioset_integrity_create(struct bio_set *bs, int pool_size) | 466 | int bioset_integrity_create(struct bio_set *bs, int pool_size) |
467 | { | 467 | { |
468 | if (bs->bio_integrity_pool) | 468 | if (mempool_initialized(&bs->bio_integrity_pool)) |
469 | return 0; | 469 | return 0; |
470 | 470 | ||
471 | bs->bio_integrity_pool = mempool_create_slab_pool(pool_size, bip_slab); | 471 | if (mempool_init_slab_pool(&bs->bio_integrity_pool, |
472 | if (!bs->bio_integrity_pool) | 472 | pool_size, bip_slab)) |
473 | return -1; | 473 | return -1; |
474 | 474 | ||
475 | bs->bvec_integrity_pool = biovec_create_pool(pool_size); | 475 | if (biovec_init_pool(&bs->bvec_integrity_pool, pool_size)) { |
476 | if (!bs->bvec_integrity_pool) { | 476 | mempool_exit(&bs->bio_integrity_pool); |
477 | mempool_destroy(bs->bio_integrity_pool); | ||
478 | return -1; | 477 | return -1; |
479 | } | 478 | } |
480 | 479 | ||
@@ -484,8 +483,8 @@ EXPORT_SYMBOL(bioset_integrity_create); | |||
484 | 483 | ||
485 | void bioset_integrity_free(struct bio_set *bs) | 484 | void bioset_integrity_free(struct bio_set *bs) |
486 | { | 485 | { |
487 | mempool_destroy(bs->bio_integrity_pool); | 486 | mempool_exit(&bs->bio_integrity_pool); |
488 | mempool_destroy(bs->bvec_integrity_pool); | 487 | mempool_exit(&bs->bvec_integrity_pool); |
489 | } | 488 | } |
490 | EXPORT_SYMBOL(bioset_integrity_free); | 489 | EXPORT_SYMBOL(bioset_integrity_free); |
491 | 490 | ||
diff --git a/block/bio.c b/block/bio.c index 53e0f0a1ed94..06df6cf2ed8c 100644 --- a/block/bio.c +++ b/block/bio.c | |||
@@ -254,7 +254,7 @@ static void bio_free(struct bio *bio) | |||
254 | bio_uninit(bio); | 254 | bio_uninit(bio); |
255 | 255 | ||
256 | if (bs) { | 256 | if (bs) { |
257 | bvec_free(bs->bvec_pool, bio->bi_io_vec, BVEC_POOL_IDX(bio)); | 257 | bvec_free(&bs->bvec_pool, bio->bi_io_vec, BVEC_POOL_IDX(bio)); |
258 | 258 | ||
259 | /* | 259 | /* |
260 | * If we have front padding, adjust the bio pointer before freeing | 260 | * If we have front padding, adjust the bio pointer before freeing |
@@ -262,7 +262,7 @@ static void bio_free(struct bio *bio) | |||
262 | p = bio; | 262 | p = bio; |
263 | p -= bs->front_pad; | 263 | p -= bs->front_pad; |
264 | 264 | ||
265 | mempool_free(p, bs->bio_pool); | 265 | mempool_free(p, &bs->bio_pool); |
266 | } else { | 266 | } else { |
267 | /* Bio was allocated by bio_kmalloc() */ | 267 | /* Bio was allocated by bio_kmalloc() */ |
268 | kfree(bio); | 268 | kfree(bio); |
@@ -454,7 +454,8 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, unsigned int nr_iovecs, | |||
454 | inline_vecs = nr_iovecs; | 454 | inline_vecs = nr_iovecs; |
455 | } else { | 455 | } else { |
456 | /* should not use nobvec bioset for nr_iovecs > 0 */ | 456 | /* should not use nobvec bioset for nr_iovecs > 0 */ |
457 | if (WARN_ON_ONCE(!bs->bvec_pool && nr_iovecs > 0)) | 457 | if (WARN_ON_ONCE(!mempool_initialized(&bs->bvec_pool) && |
458 | nr_iovecs > 0)) | ||
458 | return NULL; | 459 | return NULL; |
459 | /* | 460 | /* |
460 | * generic_make_request() converts recursion to iteration; this | 461 | * generic_make_request() converts recursion to iteration; this |
@@ -483,11 +484,11 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, unsigned int nr_iovecs, | |||
483 | bs->rescue_workqueue) | 484 | bs->rescue_workqueue) |
484 | gfp_mask &= ~__GFP_DIRECT_RECLAIM; | 485 | gfp_mask &= ~__GFP_DIRECT_RECLAIM; |
485 | 486 | ||
486 | p = mempool_alloc(bs->bio_pool, gfp_mask); | 487 | p = mempool_alloc(&bs->bio_pool, gfp_mask); |
487 | if (!p && gfp_mask != saved_gfp) { | 488 | if (!p && gfp_mask != saved_gfp) { |
488 | punt_bios_to_rescuer(bs); | 489 | punt_bios_to_rescuer(bs); |
489 | gfp_mask = saved_gfp; | 490 | gfp_mask = saved_gfp; |
490 | p = mempool_alloc(bs->bio_pool, gfp_mask); | 491 | p = mempool_alloc(&bs->bio_pool, gfp_mask); |
491 | } | 492 | } |
492 | 493 | ||
493 | front_pad = bs->front_pad; | 494 | front_pad = bs->front_pad; |
@@ -503,11 +504,11 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, unsigned int nr_iovecs, | |||
503 | if (nr_iovecs > inline_vecs) { | 504 | if (nr_iovecs > inline_vecs) { |
504 | unsigned long idx = 0; | 505 | unsigned long idx = 0; |
505 | 506 | ||
506 | bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx, bs->bvec_pool); | 507 | bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx, &bs->bvec_pool); |
507 | if (!bvl && gfp_mask != saved_gfp) { | 508 | if (!bvl && gfp_mask != saved_gfp) { |
508 | punt_bios_to_rescuer(bs); | 509 | punt_bios_to_rescuer(bs); |
509 | gfp_mask = saved_gfp; | 510 | gfp_mask = saved_gfp; |
510 | bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx, bs->bvec_pool); | 511 | bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx, &bs->bvec_pool); |
511 | } | 512 | } |
512 | 513 | ||
513 | if (unlikely(!bvl)) | 514 | if (unlikely(!bvl)) |
@@ -524,7 +525,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, unsigned int nr_iovecs, | |||
524 | return bio; | 525 | return bio; |
525 | 526 | ||
526 | err_free: | 527 | err_free: |
527 | mempool_free(p, bs->bio_pool); | 528 | mempool_free(p, &bs->bio_pool); |
528 | return NULL; | 529 | return NULL; |
529 | } | 530 | } |
530 | EXPORT_SYMBOL(bio_alloc_bioset); | 531 | EXPORT_SYMBOL(bio_alloc_bioset); |
@@ -1848,11 +1849,11 @@ EXPORT_SYMBOL_GPL(bio_trim); | |||
1848 | * create memory pools for biovec's in a bio_set. | 1849 | * create memory pools for biovec's in a bio_set. |
1849 | * use the global biovec slabs created for general use. | 1850 | * use the global biovec slabs created for general use. |
1850 | */ | 1851 | */ |
1851 | mempool_t *biovec_create_pool(int pool_entries) | 1852 | int biovec_init_pool(mempool_t *pool, int pool_entries) |
1852 | { | 1853 | { |
1853 | struct biovec_slab *bp = bvec_slabs + BVEC_POOL_MAX; | 1854 | struct biovec_slab *bp = bvec_slabs + BVEC_POOL_MAX; |
1854 | 1855 | ||
1855 | return mempool_create_slab_pool(pool_entries, bp->slab); | 1856 | return mempool_init_slab_pool(pool, pool_entries, bp->slab); |
1856 | } | 1857 | } |
1857 | 1858 | ||
1858 | void bioset_free(struct bio_set *bs) | 1859 | void bioset_free(struct bio_set *bs) |
@@ -1860,8 +1861,8 @@ void bioset_free(struct bio_set *bs) | |||
1860 | if (bs->rescue_workqueue) | 1861 | if (bs->rescue_workqueue) |
1861 | destroy_workqueue(bs->rescue_workqueue); | 1862 | destroy_workqueue(bs->rescue_workqueue); |
1862 | 1863 | ||
1863 | mempool_destroy(bs->bio_pool); | 1864 | mempool_exit(&bs->bio_pool); |
1864 | mempool_destroy(bs->bvec_pool); | 1865 | mempool_exit(&bs->bvec_pool); |
1865 | 1866 | ||
1866 | bioset_integrity_free(bs); | 1867 | bioset_integrity_free(bs); |
1867 | bio_put_slab(bs); | 1868 | bio_put_slab(bs); |
@@ -1913,15 +1914,12 @@ struct bio_set *bioset_create(unsigned int pool_size, | |||
1913 | return NULL; | 1914 | return NULL; |
1914 | } | 1915 | } |
1915 | 1916 | ||
1916 | bs->bio_pool = mempool_create_slab_pool(pool_size, bs->bio_slab); | 1917 | if (mempool_init_slab_pool(&bs->bio_pool, pool_size, bs->bio_slab)) |
1917 | if (!bs->bio_pool) | ||
1918 | goto bad; | 1918 | goto bad; |
1919 | 1919 | ||
1920 | if (flags & BIOSET_NEED_BVECS) { | 1920 | if ((flags & BIOSET_NEED_BVECS) && |
1921 | bs->bvec_pool = biovec_create_pool(pool_size); | 1921 | biovec_init_pool(&bs->bvec_pool, pool_size)) |
1922 | if (!bs->bvec_pool) | 1922 | goto bad; |
1923 | goto bad; | ||
1924 | } | ||
1925 | 1923 | ||
1926 | if (!(flags & BIOSET_NEED_RESCUER)) | 1924 | if (!(flags & BIOSET_NEED_RESCUER)) |
1927 | return bs; | 1925 | return bs; |
diff --git a/include/linux/bio.h b/include/linux/bio.h index ce547a25e8ae..720f7261d042 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -412,7 +412,7 @@ enum { | |||
412 | BIOSET_NEED_RESCUER = BIT(1), | 412 | BIOSET_NEED_RESCUER = BIT(1), |
413 | }; | 413 | }; |
414 | extern void bioset_free(struct bio_set *); | 414 | extern void bioset_free(struct bio_set *); |
415 | extern mempool_t *biovec_create_pool(int pool_entries); | 415 | extern int biovec_init_pool(mempool_t *pool, int pool_entries); |
416 | 416 | ||
417 | extern struct bio *bio_alloc_bioset(gfp_t, unsigned int, struct bio_set *); | 417 | extern struct bio *bio_alloc_bioset(gfp_t, unsigned int, struct bio_set *); |
418 | extern void bio_put(struct bio *); | 418 | extern void bio_put(struct bio *); |
@@ -722,11 +722,11 @@ struct bio_set { | |||
722 | struct kmem_cache *bio_slab; | 722 | struct kmem_cache *bio_slab; |
723 | unsigned int front_pad; | 723 | unsigned int front_pad; |
724 | 724 | ||
725 | mempool_t *bio_pool; | 725 | mempool_t bio_pool; |
726 | mempool_t *bvec_pool; | 726 | mempool_t bvec_pool; |
727 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | 727 | #if defined(CONFIG_BLK_DEV_INTEGRITY) |
728 | mempool_t *bio_integrity_pool; | 728 | mempool_t bio_integrity_pool; |
729 | mempool_t *bvec_integrity_pool; | 729 | mempool_t bvec_integrity_pool; |
730 | #endif | 730 | #endif |
731 | 731 | ||
732 | /* | 732 | /* |