All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] kill bio_clone_kmalloc and bio_clone_bioset
@ 2018-06-19  4:52 ` Christoph Hellwig
  0 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ming Lei, Boaz Harrosh, linux-block, linux-bcache, dm-devel

Hi all,

this series removes all but one users of the traditional deep bio clone,
and then moves bio_clone_bioset to its only caller so that we get rid
of the deep bio cloning in the block layer API.

Patch 1 is already in the device mapper queue for 4.18, so we should
wait for that to go in before the series is applied.  The series is
inteded as preparation work for the multi-page biovecs so that it doesn't
have to deal with the difference between single page or larger bio vecs
for cloning.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC] kill bio_clone_kmalloc and bio_clone_bioset
@ 2018-06-19  4:52 ` Christoph Hellwig
  0 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Boaz Harrosh, linux-bcache, dm-devel, Ming Lei

Hi all,

this series removes all but one users of the traditional deep bio clone,
and then moves bio_clone_bioset to its only caller so that we get rid
of the deep bio cloning in the block layer API.

Patch 1 is already in the device mapper queue for 4.18, so we should
wait for that to go in before the series is applied.  The series is
inteded as preparation work for the multi-page biovecs so that it doesn't
have to deal with the difference between single page or larger bio vecs
for cloning.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 1/6] dm: use bio_split() when splitting out the already processed bio
  2018-06-19  4:52 ` Christoph Hellwig
  (?)
@ 2018-06-19  4:52 ` Christoph Hellwig
  -1 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Ming Lei, Boaz Harrosh, linux-block, linux-bcache, dm-devel,
	Mike Snitzer, stable

From: Mike Snitzer <snitzer@redhat.com>

Use of bio_clone_bioset() is inefficient if there is no need to clone
the original bio's bio_vec array.  Best to use the bio_clone_fast()
variant.  Also, just using bio_advance() is only part of what is needed
to properly setup the clone -- it doesn't account for the various
bio_integrity() related work that also needs to be performed (see
bio_split).

Address both of these issues by switching from bio_clone_bioset() to
bio_split().

Fixes: 18a25da8 ("dm: ensure bio submission follows a depth-first tree walk")
Cc: stable@vger.kernel.org # 4.15+, requires removal of '&' before md->queue->bio_split
Reported-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: NeilBrown <neilb@suse.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
---
 drivers/md/dm.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index e65429a29c06..a3b103e8e3ce 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1606,10 +1606,9 @@ static blk_qc_t __split_and_process_bio(struct mapped_device *md,
 				 * the usage of io->orig_bio in dm_remap_zone_report()
 				 * won't be affected by this reassignment.
 				 */
-				struct bio *b = bio_clone_bioset(bio, GFP_NOIO,
-								 &md->queue->bio_split);
+				struct bio *b = bio_split(bio, bio_sectors(bio) - ci.sector_count,
+							  GFP_NOIO, &md->queue->bio_split);
 				ci.io->orig_bio = b;
-				bio_advance(bio, (bio_sectors(bio) - ci.sector_count) << 9);
 				bio_chain(b, bio);
 				ret = generic_make_request(bio);
 				break;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 2/6] bcache: don't clone bio in bch_data_verify
  2018-06-19  4:52 ` Christoph Hellwig
@ 2018-06-19  4:52   ` Christoph Hellwig
  -1 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ming Lei, Boaz Harrosh, linux-block, linux-bcache, dm-devel

We immediately overwrite the biovec array, so instead just allocate
a new bio and copy over the disk, setor and size.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/md/bcache/debug.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c
index d030ce3025a6..04d146711950 100644
--- a/drivers/md/bcache/debug.c
+++ b/drivers/md/bcache/debug.c
@@ -110,11 +110,15 @@ void bch_data_verify(struct cached_dev *dc, struct bio *bio)
 	struct bio_vec bv, cbv;
 	struct bvec_iter iter, citer = { 0 };
 
-	check = bio_clone_kmalloc(bio, GFP_NOIO);
+	check = bio_kmalloc(GFP_NOIO, bio_segments(bio));
 	if (!check)
 		return;
+	check->bi_disk = bio->bi_disk;
 	check->bi_opf = REQ_OP_READ;
+	check->bi_iter.bi_sector = bio->bi_iter.bi_sector;
+	check->bi_iter.bi_size = bio->bi_iter.bi_size;
 
+	bch_bio_map(check, NULL);
 	if (bch_bio_alloc_pages(check, GFP_NOIO))
 		goto out_put;
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 2/6] bcache: don't clone bio in bch_data_verify
@ 2018-06-19  4:52   ` Christoph Hellwig
  0 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Boaz Harrosh, linux-bcache, dm-devel, Ming Lei

We immediately overwrite the biovec array, so instead just allocate
a new bio and copy over the disk, setor and size.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/md/bcache/debug.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c
index d030ce3025a6..04d146711950 100644
--- a/drivers/md/bcache/debug.c
+++ b/drivers/md/bcache/debug.c
@@ -110,11 +110,15 @@ void bch_data_verify(struct cached_dev *dc, struct bio *bio)
 	struct bio_vec bv, cbv;
 	struct bvec_iter iter, citer = { 0 };
 
-	check = bio_clone_kmalloc(bio, GFP_NOIO);
+	check = bio_kmalloc(GFP_NOIO, bio_segments(bio));
 	if (!check)
 		return;
+	check->bi_disk = bio->bi_disk;
 	check->bi_opf = REQ_OP_READ;
+	check->bi_iter.bi_sector = bio->bi_iter.bi_sector;
+	check->bi_iter.bi_size = bio->bi_iter.bi_size;
 
+	bch_bio_map(check, NULL);
 	if (bch_bio_alloc_pages(check, GFP_NOIO))
 		goto out_put;
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 3/6] exofs: use bio_clone_fast in _write_mirror
  2018-06-19  4:52 ` Christoph Hellwig
@ 2018-06-19  4:52   ` Christoph Hellwig
  -1 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ming Lei, Boaz Harrosh, linux-block, linux-bcache, dm-devel

The mirroring code never changes the bio data or biovecs.  This means
we can reuse the biovec allocation easily instead of duplicating it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/exofs/ore.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
index 1b8b44637e70..5331a15a61f1 100644
--- a/fs/exofs/ore.c
+++ b/fs/exofs/ore.c
@@ -873,8 +873,8 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
 			struct bio *bio;
 
 			if (per_dev != master_dev) {
-				bio = bio_clone_kmalloc(master_dev->bio,
-							GFP_KERNEL);
+				bio = bio_clone_fast(master_dev->bio,
+						     GFP_KERNEL, NULL);
 				if (unlikely(!bio)) {
 					ORE_DBGMSG(
 					      "Failed to allocate BIO size=%u\n",
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 3/6] exofs: use bio_clone_fast in _write_mirror
@ 2018-06-19  4:52   ` Christoph Hellwig
  0 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Boaz Harrosh, linux-bcache, dm-devel, Ming Lei

The mirroring code never changes the bio data or biovecs.  This means
we can reuse the biovec allocation easily instead of duplicating it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/exofs/ore.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
index 1b8b44637e70..5331a15a61f1 100644
--- a/fs/exofs/ore.c
+++ b/fs/exofs/ore.c
@@ -873,8 +873,8 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
 			struct bio *bio;
 
 			if (per_dev != master_dev) {
-				bio = bio_clone_kmalloc(master_dev->bio,
-							GFP_KERNEL);
+				bio = bio_clone_fast(master_dev->bio,
+						     GFP_KERNEL, NULL);
 				if (unlikely(!bio)) {
 					ORE_DBGMSG(
 					      "Failed to allocate BIO size=%u\n",
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 4/6] block: remove bio_clone_kmalloc
  2018-06-19  4:52 ` Christoph Hellwig
@ 2018-06-19  4:52   ` Christoph Hellwig
  -1 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ming Lei, Boaz Harrosh, linux-block, linux-bcache, dm-devel

Unused now.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/bio.h | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/include/linux/bio.h b/include/linux/bio.h
index f08f5fe7bd08..430807f9f44b 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -443,12 +443,6 @@ static inline struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned int nr_iovecs)
 	return bio_alloc_bioset(gfp_mask, nr_iovecs, NULL);
 }
 
-static inline struct bio *bio_clone_kmalloc(struct bio *bio, gfp_t gfp_mask)
-{
-	return bio_clone_bioset(bio, gfp_mask, NULL);
-
-}
-
 extern blk_qc_t submit_bio(struct bio *);
 
 extern void bio_endio(struct bio *);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 4/6] block: remove bio_clone_kmalloc
@ 2018-06-19  4:52   ` Christoph Hellwig
  0 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Boaz Harrosh, linux-bcache, dm-devel, Ming Lei

Unused now.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/bio.h | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/include/linux/bio.h b/include/linux/bio.h
index f08f5fe7bd08..430807f9f44b 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -443,12 +443,6 @@ static inline struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned int nr_iovecs)
 	return bio_alloc_bioset(gfp_mask, nr_iovecs, NULL);
 }
 
-static inline struct bio *bio_clone_kmalloc(struct bio *bio, gfp_t gfp_mask)
-{
-	return bio_clone_bioset(bio, gfp_mask, NULL);
-
-}
-
 extern blk_qc_t submit_bio(struct bio *);
 
 extern void bio_endio(struct bio *);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 5/6] md: remove a bogus comment
  2018-06-19  4:52 ` Christoph Hellwig
@ 2018-06-19  4:52   ` Christoph Hellwig
  -1 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ming Lei, Boaz Harrosh, linux-block, linux-bcache, dm-devel

The function name mentioned doesn't exist, and the code next to it
doesn't match the description either.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/md/md.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 29b0cd9ec951..81f458514ac0 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -204,10 +204,6 @@ static int start_readonly;
  */
 static bool create_on_open = true;
 
-/* bio_clone_mddev
- * like bio_clone_bioset, but with a local bio set
- */
-
 struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
 			    struct mddev *mddev)
 {
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 5/6] md: remove a bogus comment
@ 2018-06-19  4:52   ` Christoph Hellwig
  0 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Boaz Harrosh, linux-bcache, dm-devel, Ming Lei

The function name mentioned doesn't exist, and the code next to it
doesn't match the description either.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/md/md.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 29b0cd9ec951..81f458514ac0 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -204,10 +204,6 @@ static int start_readonly;
  */
 static bool create_on_open = true;
 
-/* bio_clone_mddev
- * like bio_clone_bioset, but with a local bio set
- */
-
 struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
 			    struct mddev *mddev)
 {
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 6/6] block: unexport bio_clone_bioset
  2018-06-19  4:52 ` Christoph Hellwig
@ 2018-06-19  4:52   ` Christoph Hellwig
  -1 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Ming Lei, Boaz Harrosh, linux-block, linux-bcache, dm-devel

Now only used by the bounce code, so move it there and mark the function
static.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/bio.c         | 77 ---------------------------------------------
 block/bounce.c      | 69 +++++++++++++++++++++++++++++++++++++++-
 include/linux/bio.h |  1 -
 3 files changed, 68 insertions(+), 79 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 9710e275f230..43698bcff737 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -644,83 +644,6 @@ struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs)
 }
 EXPORT_SYMBOL(bio_clone_fast);
 
-/**
- * 	bio_clone_bioset - clone a bio
- * 	@bio_src: bio to clone
- *	@gfp_mask: allocation priority
- *	@bs: bio_set to allocate from
- *
- *	Clone bio. Caller will own the returned bio, but not the actual data it
- *	points to. Reference count of returned bio will be one.
- */
-struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
-			     struct bio_set *bs)
-{
-	struct bvec_iter iter;
-	struct bio_vec bv;
-	struct bio *bio;
-
-	/*
-	 * Pre immutable biovecs, __bio_clone() used to just do a memcpy from
-	 * bio_src->bi_io_vec to bio->bi_io_vec.
-	 *
-	 * We can't do that anymore, because:
-	 *
-	 *  - The point of cloning the biovec is to produce a bio with a biovec
-	 *    the caller can modify: bi_idx and bi_bvec_done should be 0.
-	 *
-	 *  - The original bio could've had more than BIO_MAX_PAGES biovecs; if
-	 *    we tried to clone the whole thing bio_alloc_bioset() would fail.
-	 *    But the clone should succeed as long as the number of biovecs we
-	 *    actually need to allocate is fewer than BIO_MAX_PAGES.
-	 *
-	 *  - Lastly, bi_vcnt should not be looked at or relied upon by code
-	 *    that does not own the bio - reason being drivers don't use it for
-	 *    iterating over the biovec anymore, so expecting it to be kept up
-	 *    to date (i.e. for clones that share the parent biovec) is just
-	 *    asking for trouble and would force extra work on
-	 *    __bio_clone_fast() anyways.
-	 */
-
-	bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
-	if (!bio)
-		return NULL;
-	bio->bi_disk		= bio_src->bi_disk;
-	bio->bi_opf		= bio_src->bi_opf;
-	bio->bi_write_hint	= bio_src->bi_write_hint;
-	bio->bi_iter.bi_sector	= bio_src->bi_iter.bi_sector;
-	bio->bi_iter.bi_size	= bio_src->bi_iter.bi_size;
-
-	switch (bio_op(bio)) {
-	case REQ_OP_DISCARD:
-	case REQ_OP_SECURE_ERASE:
-	case REQ_OP_WRITE_ZEROES:
-		break;
-	case REQ_OP_WRITE_SAME:
-		bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
-		break;
-	default:
-		bio_for_each_segment(bv, bio_src, iter)
-			bio->bi_io_vec[bio->bi_vcnt++] = bv;
-		break;
-	}
-
-	if (bio_integrity(bio_src)) {
-		int ret;
-
-		ret = bio_integrity_clone(bio, bio_src, gfp_mask);
-		if (ret < 0) {
-			bio_put(bio);
-			return NULL;
-		}
-	}
-
-	bio_clone_blkcg_association(bio, bio_src);
-
-	return bio;
-}
-EXPORT_SYMBOL(bio_clone_bioset);
-
 /**
  *	bio_add_pc_page	-	attempt to add page to bio
  *	@q: the target queue
diff --git a/block/bounce.c b/block/bounce.c
index fd31347b7836..bc63b3a2d18c 100644
--- a/block/bounce.c
+++ b/block/bounce.c
@@ -195,6 +195,73 @@ static void bounce_end_io_read_isa(struct bio *bio)
 	__bounce_end_io_read(bio, &isa_page_pool);
 }
 
+static struct bio *bounce_clone_bio(struct bio *bio_src, gfp_t gfp_mask,
+		struct bio_set *bs)
+{
+	struct bvec_iter iter;
+	struct bio_vec bv;
+	struct bio *bio;
+
+	/*
+	 * Pre immutable biovecs, __bio_clone() used to just do a memcpy from
+	 * bio_src->bi_io_vec to bio->bi_io_vec.
+	 *
+	 * We can't do that anymore, because:
+	 *
+	 *  - The point of cloning the biovec is to produce a bio with a biovec
+	 *    the caller can modify: bi_idx and bi_bvec_done should be 0.
+	 *
+	 *  - The original bio could've had more than BIO_MAX_PAGES biovecs; if
+	 *    we tried to clone the whole thing bio_alloc_bioset() would fail.
+	 *    But the clone should succeed as long as the number of biovecs we
+	 *    actually need to allocate is fewer than BIO_MAX_PAGES.
+	 *
+	 *  - Lastly, bi_vcnt should not be looked at or relied upon by code
+	 *    that does not own the bio - reason being drivers don't use it for
+	 *    iterating over the biovec anymore, so expecting it to be kept up
+	 *    to date (i.e. for clones that share the parent biovec) is just
+	 *    asking for trouble and would force extra work on
+	 *    __bio_clone_fast() anyways.
+	 */
+
+	bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
+	if (!bio)
+		return NULL;
+	bio->bi_disk		= bio_src->bi_disk;
+	bio->bi_opf		= bio_src->bi_opf;
+	bio->bi_write_hint	= bio_src->bi_write_hint;
+	bio->bi_iter.bi_sector	= bio_src->bi_iter.bi_sector;
+	bio->bi_iter.bi_size	= bio_src->bi_iter.bi_size;
+
+	switch (bio_op(bio)) {
+	case REQ_OP_DISCARD:
+	case REQ_OP_SECURE_ERASE:
+	case REQ_OP_WRITE_ZEROES:
+		break;
+	case REQ_OP_WRITE_SAME:
+		bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
+		break;
+	default:
+		bio_for_each_segment(bv, bio_src, iter)
+			bio->bi_io_vec[bio->bi_vcnt++] = bv;
+		break;
+	}
+
+	if (bio_integrity(bio_src)) {
+		int ret;
+
+		ret = bio_integrity_clone(bio, bio_src, gfp_mask);
+		if (ret < 0) {
+			bio_put(bio);
+			return NULL;
+		}
+	}
+
+	bio_clone_blkcg_association(bio, bio_src);
+
+	return bio;
+}
+
 static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
 			       mempool_t *pool)
 {
@@ -222,7 +289,7 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
 		generic_make_request(*bio_orig);
 		*bio_orig = bio;
 	}
-	bio = bio_clone_bioset(*bio_orig, GFP_NOIO, passthrough ? NULL :
+	bio = bounce_clone_bio(*bio_orig, GFP_NOIO, passthrough ? NULL :
 			&bounce_bio_set);
 
 	bio_for_each_segment_all(to, bio, i) {
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 430807f9f44b..21d07858ddef 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -429,7 +429,6 @@ extern void bio_put(struct bio *);
 
 extern void __bio_clone_fast(struct bio *, struct bio *);
 extern struct bio *bio_clone_fast(struct bio *, gfp_t, struct bio_set *);
-extern struct bio *bio_clone_bioset(struct bio *, gfp_t, struct bio_set *bs);
 
 extern struct bio_set fs_bio_set;
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 6/6] block: unexport bio_clone_bioset
@ 2018-06-19  4:52   ` Christoph Hellwig
  0 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2018-06-19  4:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Boaz Harrosh, linux-bcache, dm-devel, Ming Lei

Now only used by the bounce code, so move it there and mark the function
static.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/bio.c         | 77 ---------------------------------------------
 block/bounce.c      | 69 +++++++++++++++++++++++++++++++++++++++-
 include/linux/bio.h |  1 -
 3 files changed, 68 insertions(+), 79 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 9710e275f230..43698bcff737 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -644,83 +644,6 @@ struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs)
 }
 EXPORT_SYMBOL(bio_clone_fast);
 
-/**
- * 	bio_clone_bioset - clone a bio
- * 	@bio_src: bio to clone
- *	@gfp_mask: allocation priority
- *	@bs: bio_set to allocate from
- *
- *	Clone bio. Caller will own the returned bio, but not the actual data it
- *	points to. Reference count of returned bio will be one.
- */
-struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
-			     struct bio_set *bs)
-{
-	struct bvec_iter iter;
-	struct bio_vec bv;
-	struct bio *bio;
-
-	/*
-	 * Pre immutable biovecs, __bio_clone() used to just do a memcpy from
-	 * bio_src->bi_io_vec to bio->bi_io_vec.
-	 *
-	 * We can't do that anymore, because:
-	 *
-	 *  - The point of cloning the biovec is to produce a bio with a biovec
-	 *    the caller can modify: bi_idx and bi_bvec_done should be 0.
-	 *
-	 *  - The original bio could've had more than BIO_MAX_PAGES biovecs; if
-	 *    we tried to clone the whole thing bio_alloc_bioset() would fail.
-	 *    But the clone should succeed as long as the number of biovecs we
-	 *    actually need to allocate is fewer than BIO_MAX_PAGES.
-	 *
-	 *  - Lastly, bi_vcnt should not be looked at or relied upon by code
-	 *    that does not own the bio - reason being drivers don't use it for
-	 *    iterating over the biovec anymore, so expecting it to be kept up
-	 *    to date (i.e. for clones that share the parent biovec) is just
-	 *    asking for trouble and would force extra work on
-	 *    __bio_clone_fast() anyways.
-	 */
-
-	bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
-	if (!bio)
-		return NULL;
-	bio->bi_disk		= bio_src->bi_disk;
-	bio->bi_opf		= bio_src->bi_opf;
-	bio->bi_write_hint	= bio_src->bi_write_hint;
-	bio->bi_iter.bi_sector	= bio_src->bi_iter.bi_sector;
-	bio->bi_iter.bi_size	= bio_src->bi_iter.bi_size;
-
-	switch (bio_op(bio)) {
-	case REQ_OP_DISCARD:
-	case REQ_OP_SECURE_ERASE:
-	case REQ_OP_WRITE_ZEROES:
-		break;
-	case REQ_OP_WRITE_SAME:
-		bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
-		break;
-	default:
-		bio_for_each_segment(bv, bio_src, iter)
-			bio->bi_io_vec[bio->bi_vcnt++] = bv;
-		break;
-	}
-
-	if (bio_integrity(bio_src)) {
-		int ret;
-
-		ret = bio_integrity_clone(bio, bio_src, gfp_mask);
-		if (ret < 0) {
-			bio_put(bio);
-			return NULL;
-		}
-	}
-
-	bio_clone_blkcg_association(bio, bio_src);
-
-	return bio;
-}
-EXPORT_SYMBOL(bio_clone_bioset);
-
 /**
  *	bio_add_pc_page	-	attempt to add page to bio
  *	@q: the target queue
diff --git a/block/bounce.c b/block/bounce.c
index fd31347b7836..bc63b3a2d18c 100644
--- a/block/bounce.c
+++ b/block/bounce.c
@@ -195,6 +195,73 @@ static void bounce_end_io_read_isa(struct bio *bio)
 	__bounce_end_io_read(bio, &isa_page_pool);
 }
 
+static struct bio *bounce_clone_bio(struct bio *bio_src, gfp_t gfp_mask,
+		struct bio_set *bs)
+{
+	struct bvec_iter iter;
+	struct bio_vec bv;
+	struct bio *bio;
+
+	/*
+	 * Pre immutable biovecs, __bio_clone() used to just do a memcpy from
+	 * bio_src->bi_io_vec to bio->bi_io_vec.
+	 *
+	 * We can't do that anymore, because:
+	 *
+	 *  - The point of cloning the biovec is to produce a bio with a biovec
+	 *    the caller can modify: bi_idx and bi_bvec_done should be 0.
+	 *
+	 *  - The original bio could've had more than BIO_MAX_PAGES biovecs; if
+	 *    we tried to clone the whole thing bio_alloc_bioset() would fail.
+	 *    But the clone should succeed as long as the number of biovecs we
+	 *    actually need to allocate is fewer than BIO_MAX_PAGES.
+	 *
+	 *  - Lastly, bi_vcnt should not be looked at or relied upon by code
+	 *    that does not own the bio - reason being drivers don't use it for
+	 *    iterating over the biovec anymore, so expecting it to be kept up
+	 *    to date (i.e. for clones that share the parent biovec) is just
+	 *    asking for trouble and would force extra work on
+	 *    __bio_clone_fast() anyways.
+	 */
+
+	bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
+	if (!bio)
+		return NULL;
+	bio->bi_disk		= bio_src->bi_disk;
+	bio->bi_opf		= bio_src->bi_opf;
+	bio->bi_write_hint	= bio_src->bi_write_hint;
+	bio->bi_iter.bi_sector	= bio_src->bi_iter.bi_sector;
+	bio->bi_iter.bi_size	= bio_src->bi_iter.bi_size;
+
+	switch (bio_op(bio)) {
+	case REQ_OP_DISCARD:
+	case REQ_OP_SECURE_ERASE:
+	case REQ_OP_WRITE_ZEROES:
+		break;
+	case REQ_OP_WRITE_SAME:
+		bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
+		break;
+	default:
+		bio_for_each_segment(bv, bio_src, iter)
+			bio->bi_io_vec[bio->bi_vcnt++] = bv;
+		break;
+	}
+
+	if (bio_integrity(bio_src)) {
+		int ret;
+
+		ret = bio_integrity_clone(bio, bio_src, gfp_mask);
+		if (ret < 0) {
+			bio_put(bio);
+			return NULL;
+		}
+	}
+
+	bio_clone_blkcg_association(bio, bio_src);
+
+	return bio;
+}
+
 static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
 			       mempool_t *pool)
 {
@@ -222,7 +289,7 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
 		generic_make_request(*bio_orig);
 		*bio_orig = bio;
 	}
-	bio = bio_clone_bioset(*bio_orig, GFP_NOIO, passthrough ? NULL :
+	bio = bounce_clone_bio(*bio_orig, GFP_NOIO, passthrough ? NULL :
 			&bounce_bio_set);
 
 	bio_for_each_segment_all(to, bio, i) {
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 430807f9f44b..21d07858ddef 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -429,7 +429,6 @@ extern void bio_put(struct bio *);
 
 extern void __bio_clone_fast(struct bio *, struct bio *);
 extern struct bio *bio_clone_fast(struct bio *, gfp_t, struct bio_set *);
-extern struct bio *bio_clone_bioset(struct bio *, gfp_t, struct bio_set *bs);
 
 extern struct bio_set fs_bio_set;
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/6] bcache: don't clone bio in bch_data_verify
  2018-06-19  4:52   ` Christoph Hellwig
@ 2018-06-19  7:41     ` Coly Li
  -1 siblings, 0 replies; 19+ messages in thread
From: Coly Li @ 2018-06-19  7:41 UTC (permalink / raw)
  To: Christoph Hellwig, Jens Axboe
  Cc: Ming Lei, Boaz Harrosh, linux-block, linux-bcache, dm-devel

On 2018/6/19 12:52 PM, Christoph Hellwig wrote:
> We immediately overwrite the biovec array, so instead just allocate
> a new bio and copy over the disk, setor and size.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

It looks good to me.  Acked-by: Coly Li <colyli@suse.de>

Thanks.

Coly Li

> ---
>  drivers/md/bcache/debug.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c
> index d030ce3025a6..04d146711950 100644
> --- a/drivers/md/bcache/debug.c
> +++ b/drivers/md/bcache/debug.c
> @@ -110,11 +110,15 @@ void bch_data_verify(struct cached_dev *dc, struct bio *bio)
>  	struct bio_vec bv, cbv;
>  	struct bvec_iter iter, citer = { 0 };
>  
> -	check = bio_clone_kmalloc(bio, GFP_NOIO);
> +	check = bio_kmalloc(GFP_NOIO, bio_segments(bio));
>  	if (!check)
>  		return;
> +	check->bi_disk = bio->bi_disk;
>  	check->bi_opf = REQ_OP_READ;
> +	check->bi_iter.bi_sector = bio->bi_iter.bi_sector;
> +	check->bi_iter.bi_size = bio->bi_iter.bi_size;
>  
> +	bch_bio_map(check, NULL);
>  	if (bch_bio_alloc_pages(check, GFP_NOIO))
>  		goto out_put;
>  
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/6] bcache: don't clone bio in bch_data_verify
@ 2018-06-19  7:41     ` Coly Li
  0 siblings, 0 replies; 19+ messages in thread
From: Coly Li @ 2018-06-19  7:41 UTC (permalink / raw)
  To: Christoph Hellwig, Jens Axboe
  Cc: linux-block, Boaz Harrosh, linux-bcache, dm-devel, Ming Lei

On 2018/6/19 12:52 PM, Christoph Hellwig wrote:
> We immediately overwrite the biovec array, so instead just allocate
> a new bio and copy over the disk, setor and size.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

It looks good to me.  Acked-by: Coly Li <colyli@suse.de>

Thanks.

Coly Li

> ---
>  drivers/md/bcache/debug.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c
> index d030ce3025a6..04d146711950 100644
> --- a/drivers/md/bcache/debug.c
> +++ b/drivers/md/bcache/debug.c
> @@ -110,11 +110,15 @@ void bch_data_verify(struct cached_dev *dc, struct bio *bio)
>  	struct bio_vec bv, cbv;
>  	struct bvec_iter iter, citer = { 0 };
>  
> -	check = bio_clone_kmalloc(bio, GFP_NOIO);
> +	check = bio_kmalloc(GFP_NOIO, bio_segments(bio));
>  	if (!check)
>  		return;
> +	check->bi_disk = bio->bi_disk;
>  	check->bi_opf = REQ_OP_READ;
> +	check->bi_iter.bi_sector = bio->bi_iter.bi_sector;
> +	check->bi_iter.bi_size = bio->bi_iter.bi_size;
>  
> +	bch_bio_map(check, NULL);
>  	if (bch_bio_alloc_pages(check, GFP_NOIO))
>  		goto out_put;
>  
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] exofs: use bio_clone_fast in _write_mirror
  2018-06-19  4:52   ` Christoph Hellwig
@ 2018-06-19  7:54     ` Boaz Harrosh
  -1 siblings, 0 replies; 19+ messages in thread
From: Boaz Harrosh @ 2018-06-19  7:54 UTC (permalink / raw)
  To: Christoph Hellwig, Jens Axboe
  Cc: Ming Lei, linux-block, linux-bcache, dm-devel

On 19/06/18 07:52, Christoph Hellwig wrote:
> The mirroring code never changes the bio data or biovecs.  This means
> we can reuse the biovec allocation easily instead of duplicating it.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Thank you yes that's much better
ACK-by Boaz Harrosh <ooo@electrozaur.com>

> ---
>  fs/exofs/ore.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
> index 1b8b44637e70..5331a15a61f1 100644
> --- a/fs/exofs/ore.c
> +++ b/fs/exofs/ore.c
> @@ -873,8 +873,8 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
>  			struct bio *bio;
>  
>  			if (per_dev != master_dev) {
> -				bio = bio_clone_kmalloc(master_dev->bio,
> -							GFP_KERNEL);
> +				bio = bio_clone_fast(master_dev->bio,
> +						     GFP_KERNEL, NULL);
>  				if (unlikely(!bio)) {
>  					ORE_DBGMSG(
>  					      "Failed to allocate BIO size=%u\n",
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] exofs: use bio_clone_fast in _write_mirror
@ 2018-06-19  7:54     ` Boaz Harrosh
  0 siblings, 0 replies; 19+ messages in thread
From: Boaz Harrosh @ 2018-06-19  7:54 UTC (permalink / raw)
  To: Christoph Hellwig, Jens Axboe
  Cc: linux-block, linux-bcache, dm-devel, Ming Lei

On 19/06/18 07:52, Christoph Hellwig wrote:
> The mirroring code never changes the bio data or biovecs.  This means
> we can reuse the biovec allocation easily instead of duplicating it.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Thank you yes that's much better
ACK-by Boaz Harrosh <ooo@electrozaur.com>

> ---
>  fs/exofs/ore.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
> index 1b8b44637e70..5331a15a61f1 100644
> --- a/fs/exofs/ore.c
> +++ b/fs/exofs/ore.c
> @@ -873,8 +873,8 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp)
>  			struct bio *bio;
>  
>  			if (per_dev != master_dev) {
> -				bio = bio_clone_kmalloc(master_dev->bio,
> -							GFP_KERNEL);
> +				bio = bio_clone_fast(master_dev->bio,
> +						     GFP_KERNEL, NULL);
>  				if (unlikely(!bio)) {
>  					ORE_DBGMSG(
>  					      "Failed to allocate BIO size=%u\n",
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] kill bio_clone_kmalloc and bio_clone_bioset
  2018-06-19  4:52 ` Christoph Hellwig
@ 2018-06-20  9:12   ` Ming Lei
  -1 siblings, 0 replies; 19+ messages in thread
From: Ming Lei @ 2018-06-20  9:12 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jens Axboe, Boaz Harrosh, linux-block, linux-bcache, dm-devel

On Tue, Jun 19, 2018 at 06:52:10AM +0200, Christoph Hellwig wrote:
> Hi all,
> 
> this series removes all but one users of the traditional deep bio clone,
> and then moves bio_clone_bioset to its only caller so that we get rid
> of the deep bio cloning in the block layer API.
> 
> Patch 1 is already in the device mapper queue for 4.18, so we should
> wait for that to go in before the series is applied.  The series is
> inteded as preparation work for the multi-page biovecs so that it doesn't
> have to deal with the difference between single page or larger bio vecs
> for cloning.

Looks good cleanup:

Reviewed-by: Ming Lei <ming.lei@redhat.com>

Thanks,
Ming

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] kill bio_clone_kmalloc and bio_clone_bioset
@ 2018-06-20  9:12   ` Ming Lei
  0 siblings, 0 replies; 19+ messages in thread
From: Ming Lei @ 2018-06-20  9:12 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jens Axboe, Boaz Harrosh, linux-bcache, linux-block, dm-devel

On Tue, Jun 19, 2018 at 06:52:10AM +0200, Christoph Hellwig wrote:
> Hi all,
> 
> this series removes all but one users of the traditional deep bio clone,
> and then moves bio_clone_bioset to its only caller so that we get rid
> of the deep bio cloning in the block layer API.
> 
> Patch 1 is already in the device mapper queue for 4.18, so we should
> wait for that to go in before the series is applied.  The series is
> inteded as preparation work for the multi-page biovecs so that it doesn't
> have to deal with the difference between single page or larger bio vecs
> for cloning.

Looks good cleanup:

Reviewed-by: Ming Lei <ming.lei@redhat.com>

Thanks,
Ming

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2018-06-20  9:12 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-19  4:52 [RFC] kill bio_clone_kmalloc and bio_clone_bioset Christoph Hellwig
2018-06-19  4:52 ` Christoph Hellwig
2018-06-19  4:52 ` [PATCH 1/6] dm: use bio_split() when splitting out the already processed bio Christoph Hellwig
2018-06-19  4:52 ` [PATCH 2/6] bcache: don't clone bio in bch_data_verify Christoph Hellwig
2018-06-19  4:52   ` Christoph Hellwig
2018-06-19  7:41   ` Coly Li
2018-06-19  7:41     ` Coly Li
2018-06-19  4:52 ` [PATCH 3/6] exofs: use bio_clone_fast in _write_mirror Christoph Hellwig
2018-06-19  4:52   ` Christoph Hellwig
2018-06-19  7:54   ` Boaz Harrosh
2018-06-19  7:54     ` Boaz Harrosh
2018-06-19  4:52 ` [PATCH 4/6] block: remove bio_clone_kmalloc Christoph Hellwig
2018-06-19  4:52   ` Christoph Hellwig
2018-06-19  4:52 ` [PATCH 5/6] md: remove a bogus comment Christoph Hellwig
2018-06-19  4:52   ` Christoph Hellwig
2018-06-19  4:52 ` [PATCH 6/6] block: unexport bio_clone_bioset Christoph Hellwig
2018-06-19  4:52   ` Christoph Hellwig
2018-06-20  9:12 ` [RFC] kill bio_clone_kmalloc and bio_clone_bioset Ming Lei
2018-06-20  9:12   ` Ming Lei

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.