Fix bio_set copy
Subsystems (2)
Jens Axboe
maintainercover Fix bio_set copy
After a recent change, dm ends up doing a straight copy of a bio_set. This breaks for various items in that bio_set, most notably lists. Provide a proper helper for it, and use it.
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerPATCH 1/2 block: add bioset_init_from_src() helper
Add a helper that allows a caller to initialize a new bio_set, using the settings from an existing bio_set.
--- block/bio.c | 18 ++++++++++++++++++ include/linux/bio.h | 1 + 2 files changed, 19 insertions(+)
block/bio.c +18 -0
@@ -1967,6 +1967,24 @@ int bioset_init(struct bio_set *bs, }EXPORT_SYMBOL (bioset_init); +/* +* Initialize and setup a new bio_set, based on the settings from +* another bio_set. +*/ +int bioset_init_from_src (struct bio_set *bs,struct bio_set *src) +{ +int flags; + + flags =0 ; +if (src->bvec_pool.min_nr) + flags |=BIOSET_NEED_BVECS ; +if (src->rescue_workqueue) + flags |=BIOSET_NEED_RESCUER ; + +return bioset_init (bs, src->bio_pool.min_nr, src->front_pad, flags); +} +EXPORT_SYMBOL (bioset_init_from_src); +#ifdef CONFIG_BLK_CGROUP /**
include/linux/bio.h +1 -0
@@ -417,6 +417,7 @@ enum {extern int bioset_init (struct bio_set *,unsigned int ,unsigned int ,int flags);extern void bioset_exit (struct bio_set *);extern int biovec_init_pool (mempool_t *pool,int pool_entries); +extern int bioset_init_from_src (struct bio_set *bs,struct bio_set *src);extern struct bio *bio_alloc_bioset (gfp_t ,unsigned int ,struct bio_set *);extern void bio_put (struct bio *);
Signature · 1 line
2.17.1
Jens Axboe
maintainerPATCH 2/2 dm: use bioset_init_from_src() to copy bio_set
In reply to Jens AxboeWe can't just copy and clear a bio_set, use the bio helper to setup a new bio_set with the settings from another one.
--- drivers/md/dm.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/md/dm.c +16 -6
@@ -1953,9 +1953,10 @@ static void free_dev(struct mapped_device *md)kvfree (md); } -static void __bind_mempools (struct mapped_device *md,struct dm_table *t) +static int __bind_mempools (struct mapped_device *md,struct dm_table *t) {struct dm_md_mempools *p =dm_table_get_md_mempools (t); +int ret =0 ;if (dm_table_bio_based (t)) {/*
@@ -1982,13 +1983,16 @@ static void __bind_mempools(struct mapped_device *md, struct dm_table *t)bioset_initialized (&md->bs) || bioset_initialized(&md->io_bs)); - md->bs = p->bs; -memset (&p->bs,0 ,sizeof (p->bs)); - md->io_bs = p->io_bs; -memset (&p->io_bs,0 ,sizeof (p->io_bs)); + ret =bioset_init_from_src (&md->bs, &p->bs); +if (ret) + goto out; + ret =bioset_init_from_src (&md->io_bs, &p->io_bs); +if (ret) +bioset_exit (&md->bs); out:/* mempool bind completed, no longer need any mempools in the table */ dm_table_free_md_mempools (t); +return ret; }/*
@@ -2033,6 +2037,7 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,struct request_queue *q = md->queue;bool request_based =dm_table_request_based (t);sector_t size; +int ret;lockdep_assert_held (&md->suspend_lock);
@@ -2068,7 +2073,11 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, md->immutable_target =dm_table_get_immutable_target (t); } -__bind_mempools (md, t); + ret =__bind_mempools (md, t); +if (ret) { + old_map =ERR_PTR (ret); + goto out; + } old_map =rcu_dereference_protected (md->map,lockdep_is_held (&md->suspend_lock));rcu_assign_pointer (md->map, (void *)t);
@@ -2078,6 +2087,7 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,if (old_map)dm_sync_table (md); +out:return old_map; }
Signature · 1 line
2.17.1
Quoted 5 lines · Jens Axboe
After a recent change, dm ends up doing a straight copy of a
bio_set. This breaks for various items in thatbio_set, most notably lists. Provide a proper helper for it, and use it.
I can confirm that the issue[1] was gone with this patchset applied.
[1] https://lkml.org/lkml/2018/6/7/36
Signature · 2 lines
Regards, Li Wang
vrbagal1
Tested-byQuoted 7 lines · Li Wang
Quoted 3 lines · Jens Axboe
After a recent change, dm ends up doing a straight copy of a
bio_set. This breaks for various items in thatbio_set, most notably lists. Provide a proper helper for it, and use it.
I am not seeing the issue, I reported with this patch applied to latest mainline.
JOB ID : 5d6db9ad320b92b77cd92056fb4514c9afa0feea
JOB LOG : /root/avocado-korg/korg/results/job-2018-06-08T03.49-5d6db9a/job.log
(1/4) memhotplug.py:memstress.test_hotplug_loop: PASS (254.14 s) (2/4) memhotplug.py:memstress.test_hotplug_toggle: PASS (246.81 s) (3/4) memhotplug.py:memstress.test_dlpar_mem_hotplug: PASS (3.95 s) (4/4) memhotplug.py:memstress.test_hotplug_per_numa_node: PASS (223.96
s)
RESULTS : PASS 4 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
JOB TIME : 734.52 s
JOB HTML : /root/avocado-korg/korg/results/job-2018-06-08T03.49-5d6db9a/results.html
Quoted 18 lines
I can confirm that the issue[1] was gone with this patchset applied.
Tested-by Li Wang <[email protected]>
[1] https://lkml.org/lkml/2018/6/7/36 [1]--
Regards,
Li Wang
Links:
------
[1] https://lkml.org/lkml/2018/6/7/36
Jens Axboe
maintainerQuoted 6 lines · Li Wang
Jens Axboe <[email protected] <mailto:[email protected]>> wrote:
After a recent change, dm ends up doing a straight copy of a
bio_set. This breaks for various items in thatbio_set, most notably lists. Provide a proper helper for it, and use it.
Quoted 6 lines
I can confirm that the issue[1] was gone with this patchset applied.
Tested-by Li Wang <[email protected] <mailto:[email protected]>>
Thanks for testing, both of you, and reporting. I'll get this pushed upstream.
Signature · 1 line
Jens Axboe