summarylogtreecommitdiffstats
path: root/0140-dm-fix-bio_set-allocation.patch
diff options
context:
space:
mode:
Diffstat (limited to '0140-dm-fix-bio_set-allocation.patch')
-rw-r--r--0140-dm-fix-bio_set-allocation.patch232
1 files changed, 232 insertions, 0 deletions
diff --git a/0140-dm-fix-bio_set-allocation.patch b/0140-dm-fix-bio_set-allocation.patch
new file mode 100644
index 000000000000..a3c7dbfedd06
--- /dev/null
+++ b/0140-dm-fix-bio_set-allocation.patch
@@ -0,0 +1,232 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 8 Jun 2022 08:34:06 +0200
+Subject: [PATCH] dm: fix bio_set allocation
+
+commit 29dec90a0f1d961b93f34f910e9319d8cb23edbd upstream.
+
+The use of bioset_init_from_src mean that the pre-allocated pools weren't
+used for anything except parameter passing, and the integrity pool
+creation got completely lost for the actual live mapped_device. Fix that
+by assigning the actual preallocated dm_md_mempools to the mapped_device
+and using that for I/O instead of creating new mempools.
+
+Fixes: 2a2a4c510b76 ("dm: use bioset_init_from_src() to copy bio_set")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/dm-core.h | 11 ++++--
+ drivers/md/dm-rq.c | 2 +-
+ drivers/md/dm-table.c | 11 ------
+ drivers/md/dm.c | 83 +++++++++++++------------------------------
+ drivers/md/dm.h | 2 --
+ 5 files changed, 34 insertions(+), 75 deletions(-)
+
+diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h
+index 4277853c753515135c90391be507599cd827f573..3cd78f1e82a44fa9416927c5828254e10431b93a 100644
+--- a/drivers/md/dm-core.h
++++ b/drivers/md/dm-core.h
+@@ -32,6 +32,14 @@ struct dm_kobject_holder {
+ * access their members!
+ */
+
++/*
++ * For mempools pre-allocation at the table loading time.
++ */
++struct dm_md_mempools {
++ struct bio_set bs;
++ struct bio_set io_bs;
++};
++
+ struct mapped_device {
+ struct mutex suspend_lock;
+
+@@ -109,8 +117,7 @@ struct mapped_device {
+ /*
+ * io objects are allocated from here.
+ */
+- struct bio_set io_bs;
+- struct bio_set bs;
++ struct dm_md_mempools *mempools;
+
+ /* kobject and completion */
+ struct dm_kobject_holder kobj_holder;
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index 6087cdcaad46df50cb786fdb1f23b41efdf030a6..a83b98a8d2a993e75debd263ebefa369075c4080 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -319,7 +319,7 @@ static int setup_clone(struct request *clone, struct request *rq,
+ {
+ int r;
+
+- r = blk_rq_prep_clone(clone, rq, &tio->md->bs, gfp_mask,
++ r = blk_rq_prep_clone(clone, rq, &tio->md->mempools->bs, gfp_mask,
+ dm_rq_bio_constructor, tio);
+ if (r)
+ return r;
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index 03541cfc2317cb0e17780fa8970ab8959d47b171..4b5cf337269950b5332cc1bd7c02f393d098e880 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -1030,17 +1030,6 @@ static int dm_table_alloc_md_mempools(struct dm_table *t, struct mapped_device *
+ return 0;
+ }
+
+-void dm_table_free_md_mempools(struct dm_table *t)
+-{
+- dm_free_md_mempools(t->mempools);
+- t->mempools = NULL;
+-}
+-
+-struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t)
+-{
+- return t->mempools;
+-}
+-
+ static int setup_indexes(struct dm_table *t)
+ {
+ int i;
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index a68316f96350d0af64c1db865c48d1e97fbf95ca..83dd17abf1af95844d85fd405acc0e360890ef43 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -131,14 +131,6 @@ static int get_swap_bios(void)
+ return latch;
+ }
+
+-/*
+- * For mempools pre-allocation at the table loading time.
+- */
+-struct dm_md_mempools {
+- struct bio_set bs;
+- struct bio_set io_bs;
+-};
+-
+ struct table_device {
+ struct list_head list;
+ refcount_t count;
+@@ -573,7 +565,7 @@ static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio)
+ struct dm_target_io *tio;
+ struct bio *clone;
+
+- clone = bio_alloc_clone(bio->bi_bdev, bio, GFP_NOIO, &md->io_bs);
++ clone = bio_alloc_clone(bio->bi_bdev, bio, GFP_NOIO, &md->mempools->io_bs);
+
+ tio = clone_to_tio(clone);
+ tio->flags = 0;
+@@ -615,7 +607,7 @@ static struct bio *alloc_tio(struct clone_info *ci, struct dm_target *ti,
+ clone = &tio->clone;
+ } else {
+ clone = bio_alloc_clone(ci->bio->bi_bdev, ci->bio,
+- gfp_mask, &ci->io->md->bs);
++ gfp_mask, &ci->io->md->mempools->bs);
+ if (!clone)
+ return NULL;
+
+@@ -1775,8 +1767,7 @@ static void cleanup_mapped_device(struct mapped_device *md)
+ {
+ if (md->wq)
+ destroy_workqueue(md->wq);
+- bioset_exit(&md->bs);
+- bioset_exit(&md->io_bs);
++ dm_free_md_mempools(md->mempools);
+
+ if (md->dax_dev) {
+ dax_remove_host(md->disk);
+@@ -1948,48 +1939,6 @@ static void free_dev(struct mapped_device *md)
+ kvfree(md);
+ }
+
+-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)) {
+- /*
+- * The md may already have mempools that need changing.
+- * If so, reload bioset because front_pad may have changed
+- * because a different table was loaded.
+- */
+- bioset_exit(&md->bs);
+- bioset_exit(&md->io_bs);
+-
+- } else if (bioset_initialized(&md->bs)) {
+- /*
+- * There's no need to reload with request-based dm
+- * because the size of front_pad doesn't change.
+- * Note for future: If you are to reload bioset,
+- * prep-ed requests in the queue may refer
+- * to bio from the old bioset, so you must walk
+- * through the queue to unprep.
+- */
+- goto out;
+- }
+-
+- BUG_ON(!p ||
+- bioset_initialized(&md->bs) ||
+- bioset_initialized(&md->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;
+-}
+-
+ /*
+ * Bind a table to the device.
+ */
+@@ -2043,12 +1992,28 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
+ * immutable singletons - used to optimize dm_mq_queue_rq.
+ */
+ md->immutable_target = dm_table_get_immutable_target(t);
+- }
+
+- ret = __bind_mempools(md, t);
+- if (ret) {
+- old_map = ERR_PTR(ret);
+- goto out;
++ /*
++ * There is no need to reload with request-based dm because the
++ * size of front_pad doesn't change.
++ *
++ * Note for future: If you are to reload bioset, prep-ed
++ * requests in the queue may refer to bio from the old bioset,
++ * so you must walk through the queue to unprep.
++ */
++ if (!md->mempools) {
++ md->mempools = t->mempools;
++ t->mempools = NULL;
++ }
++ } else {
++ /*
++ * The md may already have mempools that need changing.
++ * If so, reload bioset because front_pad may have changed
++ * because a different table was loaded.
++ */
++ dm_free_md_mempools(md->mempools);
++ md->mempools = t->mempools;
++ t->mempools = NULL;
+ }
+
+ ret = dm_table_set_restrictions(t, md->queue, limits);
+diff --git a/drivers/md/dm.h b/drivers/md/dm.h
+index 9013dc1a7b0028cc98c2e99742ec5be487a753ba..968199b95fd1e216e33fbc2de208da0c9667544a 100644
+--- a/drivers/md/dm.h
++++ b/drivers/md/dm.h
+@@ -71,8 +71,6 @@ struct dm_target *dm_table_get_immutable_target(struct dm_table *t);
+ struct dm_target *dm_table_get_wildcard_target(struct dm_table *t);
+ bool dm_table_bio_based(struct dm_table *t);
+ bool dm_table_request_based(struct dm_table *t);
+-void dm_table_free_md_mempools(struct dm_table *t);
+-struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t);
+
+ void dm_lock_md_type(struct mapped_device *md);
+ void dm_unlock_md_type(struct mapped_device *md);