kill bio->bi_set
Subsystems (3)
PATCH 1/1 kill bio->bi_set
Hi,
Dunno why I didn't notice before, but ->bi_set is totally unnecessary bloat of struct bio. Just define a proper destructor for the bio and it already knows what bio_set it belongs too.
drivers/md/dm-io.c +6 -0
@@ -239,6 +239,11 @@ static void vm_dp_init(struct dpages *dp dp->context_ptr = data; } +static void dm_bio_destructor (struct bio *bio) +{ +bio_free (bio, _bios); +} +/*----------------------------------------------------------------- * IO routines that accept a list of pages. *---------------------------------------------------------------*/
@@ -263,6 +268,7 @@ static void do_region(int rw, unsigned i bio->bi_bdev = where->bdev; bio->bi_end_io = endio; bio->bi_private = io; + bio->bi_destructor = dm_bio_destructor;bio_set_region (bio, region);/*
fs/bio.c +18 -10
@@ -104,18 +104,22 @@ static inline struct bio_vec *bvec_allocreturn bvl; } -/* -* default destructor for a bio allocated with bio_alloc_bioset() -*/ -static void bio_destructor (struct bio *bio) +void bio_free (struct bio *bio,struct bio_set *bio_set) {const int pool_idx =BIO_POOL_IDX (bio); -struct bio_set *bs = bio->bi_set;BIO_BUG_ON (pool_idx >=BIOVEC_NR_POOLS ); -mempool_free (bio->bi_io_vec, bs->bvec_pools[pool_idx]); -mempool_free (bio, bs->bio_pool); +mempool_free (bio->bi_io_vec, fs_bio_set->bvec_pools[pool_idx]); +mempool_free (bio, fs_bio_set->bio_pool); +} + +/* +* default destructor for a bio allocated with bio_alloc_bioset() +*/ +static void bio_fs_destructor (struct bio *bio) +{ +bio_free (bio, fs_bio_set); }inline void bio_init (struct bio *bio)
@@ -171,8 +175,6 @@ struct bio *bio_alloc_bioset(unsigned in bio->bi_max_vecs = bvec_slabs[idx].nr_vecs; } bio->bi_io_vec = bvl; - bio->bi_destructor = bio_destructor; - bio->bi_set = bs; } out:return bio;
@@ -180,7 +182,12 @@ out:struct bio *bio_alloc (unsigned int __nocast gfp_mask,int nr_iovecs) { -return bio_alloc_bioset (gfp_mask, nr_iovecs, fs_bio_set); +struct bio *bio =bio_alloc_bioset (gfp_mask, nr_iovecs, fs_bio_set); + +if (bio) + bio->bi_destructor = bio_fs_destructor; + +return bio; }void zero_fill_bio (struct bio *bio)
@@ -1078,6 +1085,7 @@ subsys_initcall(init_bio);EXPORT_SYMBOL (bio_alloc);EXPORT_SYMBOL (bio_put); +EXPORT_SYMBOL (bio_free);EXPORT_SYMBOL (bio_endio);EXPORT_SYMBOL (bio_init);EXPORT_SYMBOL (__bio_clone);
include/linux/bio.h +1 -1
@@ -111,7 +111,6 @@ struct bio {void *bi_private;bio_destructor_t *bi_destructor;/* destructor */ -struct bio_set *bi_set;/* memory pools set */ };/*
@@ -280,6 +279,7 @@ extern void bioset_free(struct bio_set *extern struct bio *bio_alloc (unsigned int __nocast ,int );extern struct bio *bio_alloc_bioset (unsigned int __nocast ,int ,struct bio_set *);extern void bio_put (struct bio *); +extern void bio_free (struct bio *,struct bio_set *);extern void bio_endio (struct bio *,unsigned int ,int );struct request_queue ;
Signature · 1 line
Jens Axboe
Quoted 3 lines · Jens Axboe
Dunno why I didn't notice before, but ->bi_set is totally unnecessary bloat of struct bio. Just define a proper destructor for the bio and it already knows what
bio_setit belongs too.
This causes crashes on my computer.
fs/bio.c static inline struct bio_vec *bvec_alloc · line 115
Quoted 12 lines
fs/bio.c +4
-3+void bio_free (struct bio *bio,struct bio_set *bio_set) {const int pool_idx =BIO_POOL_IDX (bio); -struct bio_set *bs = bio->bi_set;BIO_BUG_ON (pool_idx >=BIOVEC_NR_POOLS ); -mempool_free (bio->bi_io_vec, bs->bvec_pools[pool_idx]); -mempool_free (bio, bs->bio_pool); +mempool_free (bio->bi_io_vec, fs_bio_set->bvec_pools[pool_idx]); +mempool_free (bio, fs_bio_set->bio_pool); +}
This function uses fs_bio_set instead of the function parameter bio_set.
fs/bio.c struct bio *bio_alloc_bioset(unsigned in · line 178
Quoted 7 lines
fs/bio.c +0
-2@@ -171,8 +175,6 @@ struct bio *bio_alloc_bioset(unsigned in bio->bi_max_vecs = bvec_slabs[idx].nr_vecs; } bio->bi_io_vec = bvl; - bio->bi_destructor = bio_destructor; - bio->bi_set = bs; }
This change means that all code that calls bio_alloc_bioset() must now set bi_destructor, but this is forgotten in bio_clone() in bio.c and in split_bvec() in dm.c.
Signature · 2 lines
Peter Osterlund - [email protected] http://web.telia.com/~u89404340
Quoted 7 lines · Peter Osterlund
Quoted 3 lines · Jens Axboe
Dunno why I didn't notice before, but ->bi_set is totally unnecessary bloat of struct bio. Just define a proper destructor for the bio and it already knows what
bio_setit belongs too.This causes crashes on my computer.
Did I neglect to mention it was untested? :)
Quoted 7 lines
Quoted 7 lines
fs/bio.c +1
-1+void bio_free (struct bio *bio,struct bio_set *bio_set) {const int pool_idx =BIO_POOL_IDX (bio); -struct bio_set *bs = bio->bi_set;BIO_BUG_ON (pool_idx >=BIOVEC_NR_POOLS );
Quoted 8 lines
fs/bio.c static inline struct bio_vec *bvec_alloc · line 115
Quoted 5 lines
fs/bio.c +3
-2-mempool_free (bio->bi_io_vec, bs->bvec_pools[pool_idx]); -mempool_free (bio, bs->bio_pool); +mempool_free (bio->bi_io_vec, fs_bio_set->bvec_pools[pool_idx]); +mempool_free (bio, fs_bio_set->bio_pool); +}This function uses
fs_bio_setinstead of the function parameterbio_set.
Clear mistake, thanks.
Quoted 9 lines
fs/bio.c struct bio *bio_alloc_bioset(unsigned in · line 178
Quoted 7 lines
fs/bio.c +0
-2@@ -171,8 +175,6 @@ struct bio *bio_alloc_bioset(unsigned in bio->bi_max_vecs = bvec_slabs[idx].nr_vecs; } bio->bi_io_vec = bvl; - bio->bi_destructor = bio_destructor; - bio->bi_set = bs; }This change means that all code that calls
bio_alloc_bioset()must now
Correct. The alternative was to require a destructor function passed into bio_alloc_bioset().
Quoted 2 lines
set
bi_destructor, but this is forgotten inbio_clone()inbio.cand insplit_bvec()indm.c.
Thanks, I'll go over these and submit a fixed version.
Signature · 1 line
Jens Axboe
Quoted 10 lines · Jens Axboe
Quoted 7 lines · Peter Osterlund
Quoted 3 lines · Jens Axboe
Dunno why I didn't notice before, but ->bi_set is totally unnecessary bloat of struct bio. Just define a proper destructor for the bio and it already knows what
bio_setit belongs too.This causes crashes on my computer.
Did I neglect to mention it was untested? :)
...
Quoted 1 line
Thanks, I'll go over these and submit a fixed version.
I fixed this myself. The patch below is tested with dm-crypt on top of pktcdvd on top of usb-storage, and worked fine in my tests.
---
drivers/md/dm-io.c | 6 ++++++ drivers/md/dm.c | 6 ++++++ fs/bio.c | 32 +++++++++++++++++++++----------- include/linux/bio.h | 2 +- 4 files changed, 34 insertions(+), 12 deletions(-)
drivers/md/dm-io.c +6 -0
@@ -239,6 +239,11 @@ static void vm_dp_init(struct dpages *dp dp->context_ptr = data; } +static void dm_bio_destructor (struct bio *bio) +{ +bio_free (bio, _bios); +} +/*----------------------------------------------------------------- * IO routines that accept a list of pages. *---------------------------------------------------------------*/
@@ -263,6 +268,7 @@ static void do_region(int rw, unsigned i bio->bi_bdev = where->bdev; bio->bi_end_io = endio; bio->bi_private = io; + bio->bi_destructor = dm_bio_destructor;bio_set_region (bio, region);/*
drivers/md/dm.c +6 -0
@@ -399,6 +399,11 @@ struct clone_info {unsigned short idx; }; +static void dm_bio_destructor (struct bio *bio) +{ +bio_free (bio, dm_set); +} +/* * Creates a little bio that is just does part of a bvec. */
@@ -410,6 +415,7 @@ static struct bio *split_bvec(struct biostruct bio_vec *bv = bio->bi_io_vec + idx; clone =bio_alloc_bioset (GFP_NOIO ,1 , dm_set); + clone->bi_destructor = dm_bio_destructor; *clone->bi_io_vec = *bv; clone->bi_sector = sector;
fs/bio.c +21 -11
@@ -104,18 +104,22 @@ static inline struct bio_vec *bvec_allocreturn bvl; } -/* -* default destructor for a bio allocated with bio_alloc_bioset() -*/ -static void bio_destructor (struct bio *bio) +void bio_free (struct bio *bio,struct bio_set *bio_set) {const int pool_idx =BIO_POOL_IDX (bio); -struct bio_set *bs = bio->bi_set;BIO_BUG_ON (pool_idx >=BIOVEC_NR_POOLS ); -mempool_free (bio->bi_io_vec, bs->bvec_pools[pool_idx]); -mempool_free (bio, bs->bio_pool); +mempool_free (bio->bi_io_vec, bio_set->bvec_pools[pool_idx]); +mempool_free (bio, bio_set->bio_pool); +} + +/* +* default destructor for a bio allocated with bio_alloc_bioset() +*/ +static void bio_fs_destructor (struct bio *bio) +{ +bio_free (bio, fs_bio_set); }inline void bio_init (struct bio *bio)
@@ -171,8 +175,6 @@ struct bio *bio_alloc_bioset(unsigned in bio->bi_max_vecs = bvec_slabs[idx].nr_vecs; } bio->bi_io_vec = bvl; - bio->bi_destructor = bio_destructor; - bio->bi_set = bs; } out:return bio;
@@ -180,7 +182,12 @@ out:struct bio *bio_alloc (unsigned int __nocast gfp_mask,int nr_iovecs) { -return bio_alloc_bioset (gfp_mask, nr_iovecs, fs_bio_set); +struct bio *bio =bio_alloc_bioset (gfp_mask, nr_iovecs, fs_bio_set); + +if (bio) + bio->bi_destructor = bio_fs_destructor; + +return bio; }void zero_fill_bio (struct bio *bio)
@@ -276,8 +283,10 @@ struct bio *bio_clone(struct bio *bio, u {struct bio *b =bio_alloc_bioset (gfp_mask, bio->bi_max_vecs, fs_bio_set); -if (b) +if (b) { + b->bi_destructor = bio_fs_destructor;__bio_clone (b, bio); + }return b; }
@@ -1078,6 +1087,7 @@ subsys_initcall(init_bio);EXPORT_SYMBOL (bio_alloc);EXPORT_SYMBOL (bio_put); +EXPORT_SYMBOL (bio_free);EXPORT_SYMBOL (bio_endio);EXPORT_SYMBOL (bio_init);EXPORT_SYMBOL (__bio_clone);
include/linux/bio.h +1 -1
@@ -111,7 +111,6 @@ struct bio {void *bi_private;bio_destructor_t *bi_destructor;/* destructor */ -struct bio_set *bi_set;/* memory pools set */ };/*
@@ -280,6 +279,7 @@ extern void bioset_free(struct bio_set *extern struct bio *bio_alloc (unsigned int __nocast ,int );extern struct bio *bio_alloc_bioset (unsigned int __nocast ,int ,struct bio_set *);extern void bio_put (struct bio *); +extern void bio_free (struct bio *,struct bio_set *);extern void bio_endio (struct bio *,unsigned int ,int );struct request_queue ;
Signature · 2 lines
Peter Osterlund - [email protected] http://web.telia.com/~u89404340
Quoted 9 lines · Peter Osterlund
Quoted 7 lines · Jens Axboe
Quoted 6 lines · Peter Osterlund
Quoted 3 lines · Jens Axboe
Dunno why I didn't notice before, but ->bi_set is totally unnecessary bloat of struct bio. Just define a proper destructor for the bio and it already knows what
bio_setit belongs too.
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
This causes crashes on my computer.
Did I neglect to mention it was untested? :)
...
Quoted 1 line
Thanks, I'll go over these and submit a fixed version.
I fixed this myself. The patch below is tested with dm-crypt on top of pktcdvd on top of usb-storage, and worked fine in my tests.
Thanks! I was travelling, so I didn't get to it myself.
Signature · 1 line
Jens Axboe