linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/5] md: use bio_clone_fast()
@ 2017-02-10 10:56 Ming Lei
  2017-02-10 10:56 ` [PATCH v1 1/5] block: introduce bio_clone_bioset_partial() Ming Lei
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Ming Lei @ 2017-02-10 10:56 UTC (permalink / raw)
  To: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown
  Cc: Ming Lei

Hi,

This patches replaces bio_clone() with bio_fast_clone() in
bio_clone_mddev() because:

1) bio_clone_mddev() is used in raid normal I/O and isn't in
resync I/O path, and all the direct access to bvec table in
raid happens on resync I/O only except for write behind of raid1.
Write behind is treated specially, so the replacement is safe.

2) for write behind, bio_clone() is kept, but this patchset
introduces bio_clone_bioset_partial() to just clone one specific 
bvecs range instead of whole table. Then write behind is improved
too.

V1:
	1) don't introduce bio_clone_slow_mddev_partial()
	2) return failure if mddev->bio_set can't be created
	3) remove check in bio_clone_mddev() as suggested by
	Christoph Hellwig.
	4) rename bio_clone_mddev() as bio_clone_fast_mddev()


Ming Lei (5):
  block: introduce bio_clone_bioset_partial()
  md/raid1: use bio_clone_bioset_partial() in case of write behind
  md: fail if mddev->bio_set can't be created
  md: remove unnecessary check on mddev
  md: fast clone bio in bio_clone_mddev()

 block/bio.c         | 61 +++++++++++++++++++++++++++++++++++++++++------------
 drivers/md/faulty.c |  2 +-
 drivers/md/md.c     | 14 ++++++------
 drivers/md/md.h     |  4 ++--
 drivers/md/raid1.c  | 26 ++++++++++++++++-------
 drivers/md/raid10.c | 11 +++++-----
 drivers/md/raid5.c  |  4 ++--
 include/linux/bio.h | 11 ++++++++--
 8 files changed, 92 insertions(+), 41 deletions(-)

-- 
2.7.4

Thanks,
Ming

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

* [PATCH v1 1/5] block: introduce bio_clone_bioset_partial()
  2017-02-10 10:56 [PATCH v1 0/5] md: use bio_clone_fast() Ming Lei
@ 2017-02-10 10:56 ` Ming Lei
  2017-02-13 13:46   ` Christoph Hellwig
  2017-02-10 10:56 ` [PATCH v1 2/5] md/raid1: use bio_clone_bioset_partial() in case of write behind Ming Lei
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Ming Lei @ 2017-02-10 10:56 UTC (permalink / raw)
  To: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown
  Cc: Ming Lei

md still need bio clone(not the fast version) for behind write,
and it is more efficient to use bio_clone_bioset_partial().

The idea is simple and just copy the bvecs range specified from
parameters.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 block/bio.c         | 61 +++++++++++++++++++++++++++++++++++++++++------------
 include/linux/bio.h | 11 ++++++++--
 2 files changed, 57 insertions(+), 15 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 4b564d0c3e29..5eec5e08417f 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -625,21 +625,20 @@ 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)
+static struct bio *__bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
+				      struct bio_set *bs, int offset,
+				      int size)
 {
 	struct bvec_iter iter;
 	struct bio_vec bv;
 	struct bio *bio;
+	struct bvec_iter iter_src = bio_src->bi_iter;
+
+	/* for supporting partial clone */
+	if (offset || size != bio_src->bi_iter.bi_size) {
+		bio_advance_iter(bio_src, &iter_src, offset);
+		iter_src.bi_size = size;
+	}
 
 	/*
 	 * Pre immutable biovecs, __bio_clone() used to just do a memcpy from
@@ -663,7 +662,8 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
 	 *    __bio_clone_fast() anyways.
 	 */
 
-	bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
+	bio = bio_alloc_bioset(gfp_mask, __bio_segments(bio_src,
+			       &iter_src), bs);
 	if (!bio)
 		return NULL;
 	bio->bi_bdev		= bio_src->bi_bdev;
@@ -680,7 +680,7 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
 		bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
 		break;
 	default:
-		bio_for_each_segment(bv, bio_src, iter)
+		__bio_for_each_segment(bv, bio_src, iter, iter_src)
 			bio->bi_io_vec[bio->bi_vcnt++] = bv;
 		break;
 	}
@@ -699,9 +699,44 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
 
 	return bio;
 }
+
+/**
+ * 	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)
+{
+	return __bio_clone_bioset(bio_src, gfp_mask, bs, 0,
+				  bio_src->bi_iter.bi_size);
+}
 EXPORT_SYMBOL(bio_clone_bioset);
 
 /**
+ * 	bio_clone_bioset_partial - clone a partial bio
+ * 	@bio_src: bio to clone
+ *	@gfp_mask: allocation priority
+ *	@bs: bio_set to allocate from
+ *	@offset: cloned starting from the offset
+ *	@size: size for the cloned bio
+ *
+ *	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_partial(struct bio *bio_src, gfp_t gfp_mask,
+				     struct bio_set *bs, int offset,
+				     int size)
+{
+	return __bio_clone_bioset(bio_src, gfp_mask, bs, offset, size);
+}
+EXPORT_SYMBOL(bio_clone_bioset_partial);
+
+/**
  *	bio_add_pc_page	-	attempt to add page to bio
  *	@q: the target queue
  *	@bio: destination bio
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 7cf8a6c70a3f..8e521194f6fc 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -183,7 +183,7 @@ static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
 
 #define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)
 
-static inline unsigned bio_segments(struct bio *bio)
+static inline unsigned __bio_segments(struct bio *bio, struct bvec_iter *bvec)
 {
 	unsigned segs = 0;
 	struct bio_vec bv;
@@ -205,12 +205,17 @@ static inline unsigned bio_segments(struct bio *bio)
 		break;
 	}
 
-	bio_for_each_segment(bv, bio, iter)
+	__bio_for_each_segment(bv, bio, iter, *bvec)
 		segs++;
 
 	return segs;
 }
 
+static inline unsigned bio_segments(struct bio *bio)
+{
+	return __bio_segments(bio, &bio->bi_iter);
+}
+
 /*
  * get a reference to a bio, so it won't disappear. the intended use is
  * something like:
@@ -384,6 +389,8 @@ 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 *bio_clone_bioset_partial(struct bio *, gfp_t,
+					    struct bio_set *, int, int);
 
 extern struct bio_set *fs_bio_set;
 
-- 
2.7.4

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

* [PATCH v1 2/5] md/raid1: use bio_clone_bioset_partial() in case of write behind
  2017-02-10 10:56 [PATCH v1 0/5] md: use bio_clone_fast() Ming Lei
  2017-02-10 10:56 ` [PATCH v1 1/5] block: introduce bio_clone_bioset_partial() Ming Lei
@ 2017-02-10 10:56 ` Ming Lei
  2017-02-13 13:48   ` Christoph Hellwig
  2017-02-10 10:56 ` [PATCH v1 3/5] md: fail if mddev->bio_set can't be created Ming Lei
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Ming Lei @ 2017-02-10 10:56 UTC (permalink / raw)
  To: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown
  Cc: Ming Lei

Write behind need to replace pages in bio's bvecs, and we have
to clone a fresh bio with new bvec table, so use the introduced
bio_clone_bioset_partial() for it.

For other bio_clone_mddev() cases, we will use fast clone since
they don't need to touch bvec table.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 drivers/md/raid1.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 830ff2b20346..4d7852c6ae97 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1341,13 +1341,12 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
 
 	first_clone = 1;
 	for (i = 0; i < disks; i++) {
-		struct bio *mbio;
+		struct bio *mbio = NULL;
+		int offset;
 		if (!r1_bio->bios[i])
 			continue;
 
-		mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-		bio_trim(mbio, r1_bio->sector - bio->bi_iter.bi_sector,
-			 max_sectors);
+		offset = r1_bio->sector - bio->bi_iter.bi_sector;
 
 		if (first_clone) {
 			/* do behind I/O ?
@@ -1357,8 +1356,13 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
 			if (bitmap &&
 			    (atomic_read(&bitmap->behind_writes)
 			     < mddev->bitmap_info.max_write_behind) &&
-			    !waitqueue_active(&bitmap->behind_wait))
+			    !waitqueue_active(&bitmap->behind_wait)) {
+				mbio = bio_clone_bioset_partial(bio, GFP_NOIO,
+								mddev->bio_set,
+								offset,
+								max_sectors);
 				alloc_behind_pages(mbio, r1_bio);
+			}
 
 			bitmap_startwrite(bitmap, r1_bio->sector,
 					  r1_bio->sectors,
@@ -1366,6 +1370,12 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
 						   &r1_bio->state));
 			first_clone = 0;
 		}
+
+		if (!mbio) {
+			mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+			bio_trim(mbio, offset, max_sectors);
+		}
+
 		if (r1_bio->behind_bvecs) {
 			struct bio_vec *bvec;
 			int j;
-- 
2.7.4

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

* [PATCH v1 3/5] md: fail if mddev->bio_set can't be created
  2017-02-10 10:56 [PATCH v1 0/5] md: use bio_clone_fast() Ming Lei
  2017-02-10 10:56 ` [PATCH v1 1/5] block: introduce bio_clone_bioset_partial() Ming Lei
  2017-02-10 10:56 ` [PATCH v1 2/5] md/raid1: use bio_clone_bioset_partial() in case of write behind Ming Lei
@ 2017-02-10 10:56 ` Ming Lei
  2017-02-13 13:45   ` Christoph Hellwig
  2017-02-10 10:56 ` [PATCH v1 4/5] md: remove unnecessary check on mddev Ming Lei
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Ming Lei @ 2017-02-10 10:56 UTC (permalink / raw)
  To: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown
  Cc: Ming Lei

The current behaviour is to fall back to allocate
bio from 'fs_bio_set', that isn't a correct way
because it might cause deadlock.

So this patch simply return failure if mddev->bio_set
can't be created.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 drivers/md/md.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 4c1b82defa78..3425c2b779a6 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5270,8 +5270,11 @@ int md_run(struct mddev *mddev)
 		sysfs_notify_dirent_safe(rdev->sysfs_state);
 	}
 
-	if (mddev->bio_set == NULL)
+	if (mddev->bio_set == NULL) {
 		mddev->bio_set = bioset_create(BIO_POOL_SIZE, 0);
+		if (!mddev->bio_set)
+			return -ENOMEM;
+	}
 
 	spin_lock(&pers_lock);
 	pers = find_pers(mddev->level, mddev->clevel);
-- 
2.7.4

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

* [PATCH v1 4/5] md: remove unnecessary check on mddev
  2017-02-10 10:56 [PATCH v1 0/5] md: use bio_clone_fast() Ming Lei
                   ` (2 preceding siblings ...)
  2017-02-10 10:56 ` [PATCH v1 3/5] md: fail if mddev->bio_set can't be created Ming Lei
@ 2017-02-10 10:56 ` Ming Lei
  2017-02-13 13:49   ` Christoph Hellwig
  2017-02-10 10:56 ` [PATCH v1 5/5] md: fast clone bio in bio_clone_mddev() Ming Lei
  2017-02-11  0:38 ` [PATCH v1 0/5] md: use bio_clone_fast() Shaohua Li
  5 siblings, 1 reply; 15+ messages in thread
From: Ming Lei @ 2017-02-10 10:56 UTC (permalink / raw)
  To: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown
  Cc: Ming Lei

mddev is never NULL and neither is ->bio_set, so
remove the check.

Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 drivers/md/md.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3425c2b779a6..2835f09b9e71 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -193,9 +193,6 @@ EXPORT_SYMBOL_GPL(bio_alloc_mddev);
 struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
 			    struct mddev *mddev)
 {
-	if (!mddev || !mddev->bio_set)
-		return bio_clone(bio, gfp_mask);
-
 	return bio_clone_bioset(bio, gfp_mask, mddev->bio_set);
 }
 EXPORT_SYMBOL_GPL(bio_clone_mddev);
-- 
2.7.4

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

* [PATCH v1 5/5] md: fast clone bio in bio_clone_mddev()
  2017-02-10 10:56 [PATCH v1 0/5] md: use bio_clone_fast() Ming Lei
                   ` (3 preceding siblings ...)
  2017-02-10 10:56 ` [PATCH v1 4/5] md: remove unnecessary check on mddev Ming Lei
@ 2017-02-10 10:56 ` Ming Lei
  2017-02-13 13:49   ` Christoph Hellwig
  2017-02-11  0:38 ` [PATCH v1 0/5] md: use bio_clone_fast() Shaohua Li
  5 siblings, 1 reply; 15+ messages in thread
From: Ming Lei @ 2017-02-10 10:56 UTC (permalink / raw)
  To: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown
  Cc: Ming Lei

Firstly bio_clone_mddev() is used in raid normal I/O and isn't
in resync I/O path.

Secondly all the direct access to bvec table in raid happens on
resync I/O except for write behind of raid1, in which we still
use bio_clone() for allocating new bvec table.

So this patch replaces bio_clone() with bio_clone_fast()
in bio_clone_mddev().

Rename bio_clone_mddev() as bio_clone_fast_mddev() too, as
suggested by Christoph Hellwig.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 drivers/md/faulty.c |  2 +-
 drivers/md/md.c     |  6 +++---
 drivers/md/md.h     |  4 ++--
 drivers/md/raid1.c  |  8 ++++----
 drivers/md/raid10.c | 11 +++++------
 drivers/md/raid5.c  |  4 ++--
 6 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 685aa2d77e25..f80e7b8f8c40 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -214,7 +214,7 @@ static void faulty_make_request(struct mddev *mddev, struct bio *bio)
 		}
 	}
 	if (failit) {
-		struct bio *b = bio_clone_mddev(bio, GFP_NOIO, mddev);
+		struct bio *b = bio_clone_fast_mddev(bio, GFP_NOIO, mddev);
 
 		b->bi_bdev = conf->rdev->bdev;
 		b->bi_private = bio;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 2835f09b9e71..d45e8d1382ad 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -190,12 +190,12 @@ struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
 }
 EXPORT_SYMBOL_GPL(bio_alloc_mddev);
 
-struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
+struct bio *bio_clone_fast_mddev(struct bio *bio, gfp_t gfp_mask,
 			    struct mddev *mddev)
 {
-	return bio_clone_bioset(bio, gfp_mask, mddev->bio_set);
+	return bio_clone_fast(bio, gfp_mask, mddev->bio_set);
 }
-EXPORT_SYMBOL_GPL(bio_clone_mddev);
+EXPORT_SYMBOL_GPL(bio_clone_fast_mddev);
 
 /*
  * We have a system wide 'event count' that is incremented
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 968bbe72b237..88d0a101fb4c 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -673,8 +673,8 @@ extern void md_rdev_clear(struct md_rdev *rdev);
 
 extern void mddev_suspend(struct mddev *mddev);
 extern void mddev_resume(struct mddev *mddev);
-extern struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
-				   struct mddev *mddev);
+extern struct bio *bio_clone_fast_mddev(struct bio *bio, gfp_t gfp_mask,
+					struct mddev *mddev);
 extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
 				   struct mddev *mddev);
 
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 4d7852c6ae97..9e0b5a5ec0bc 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1108,7 +1108,7 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
 	r1_bio->read_disk = rdisk;
 	r1_bio->start_next_window = 0;
 
-	read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+	read_bio = bio_clone_fast_mddev(bio, GFP_NOIO, mddev);
 	bio_trim(read_bio, r1_bio->sector - bio->bi_iter.bi_sector,
 		 max_sectors);
 
@@ -1372,7 +1372,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
 		}
 
 		if (!mbio) {
-			mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+			mbio = bio_clone_fast_mddev(bio, GFP_NOIO, mddev);
 			bio_trim(mbio, offset, max_sectors);
 		}
 
@@ -2283,7 +2283,7 @@ static int narrow_write_error(struct r1bio *r1_bio, int i)
 
 			wbio->bi_vcnt = vcnt;
 		} else {
-			wbio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev);
+			wbio = bio_clone_fast_mddev(r1_bio->master_bio, GFP_NOIO, mddev);
 		}
 
 		bio_set_op_attrs(wbio, REQ_OP_WRITE, 0);
@@ -2421,7 +2421,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
 		const unsigned long do_sync
 			= r1_bio->master_bio->bi_opf & REQ_SYNC;
 		r1_bio->read_disk = disk;
-		bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev);
+		bio = bio_clone_fast_mddev(r1_bio->master_bio, GFP_NOIO, mddev);
 		bio_trim(bio, r1_bio->sector - bio->bi_iter.bi_sector,
 			 max_sectors);
 		r1_bio->bios[r1_bio->read_disk] = bio;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 6bc5c2a85160..406d6651fd4c 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1132,7 +1132,7 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
 	}
 	slot = r10_bio->read_slot;
 
-	read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+	read_bio = bio_clone_fast_mddev(bio, GFP_NOIO, mddev);
 	bio_trim(read_bio, r10_bio->sector - bio->bi_iter.bi_sector,
 		 max_sectors);
 
@@ -1406,7 +1406,7 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
 		int d = r10_bio->devs[i].devnum;
 		if (r10_bio->devs[i].bio) {
 			struct md_rdev *rdev = conf->mirrors[d].rdev;
-			mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+			mbio = bio_clone_fast_mddev(bio, GFP_NOIO, mddev);
 			bio_trim(mbio, r10_bio->sector - bio->bi_iter.bi_sector,
 				 max_sectors);
 			r10_bio->devs[i].bio = mbio;
@@ -1457,7 +1457,7 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
 				smp_mb();
 				rdev = conf->mirrors[d].rdev;
 			}
-			mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+			mbio = bio_clone_fast_mddev(bio, GFP_NOIO, mddev);
 			bio_trim(mbio, r10_bio->sector - bio->bi_iter.bi_sector,
 				 max_sectors);
 			r10_bio->devs[i].repl_bio = mbio;
@@ -2565,7 +2565,7 @@ static int narrow_write_error(struct r10bio *r10_bio, int i)
 		if (sectors > sect_to_write)
 			sectors = sect_to_write;
 		/* Write at 'sector' for 'sectors' */
-		wbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+		wbio = bio_clone_fast_mddev(bio, GFP_NOIO, mddev);
 		bio_trim(wbio, sector - bio->bi_iter.bi_sector, sectors);
 		wsector = r10_bio->devs[i].addr + (sector - r10_bio->sector);
 		wbio->bi_iter.bi_sector = wsector +
@@ -2641,8 +2641,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
 			   mdname(mddev),
 			   bdevname(rdev->bdev, b),
 			   (unsigned long long)r10_bio->sector);
-	bio = bio_clone_mddev(r10_bio->master_bio,
-			      GFP_NOIO, mddev);
+	bio = bio_clone_fast_mddev(r10_bio->master_bio, GFP_NOIO, mddev);
 	bio_trim(bio, r10_bio->sector - bio->bi_iter.bi_sector, max_sectors);
 	r10_bio->devs[slot].bio = bio;
 	r10_bio->devs[slot].rdev = rdev;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 34f76615d620..b0bf647dd414 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5056,9 +5056,9 @@ static int raid5_read_one_chunk(struct mddev *mddev, struct bio *raid_bio)
 		return 0;
 	}
 	/*
-	 * use bio_clone_mddev to make a copy of the bio
+	 * use bio_clone_fast_mddev to make a copy of the bio
 	 */
-	align_bi = bio_clone_mddev(raid_bio, GFP_NOIO, mddev);
+	align_bi = bio_clone_fast_mddev(raid_bio, GFP_NOIO, mddev);
 	if (!align_bi)
 		return 0;
 	/*
-- 
2.7.4

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

* Re: [PATCH v1 0/5] md: use bio_clone_fast()
  2017-02-10 10:56 [PATCH v1 0/5] md: use bio_clone_fast() Ming Lei
                   ` (4 preceding siblings ...)
  2017-02-10 10:56 ` [PATCH v1 5/5] md: fast clone bio in bio_clone_mddev() Ming Lei
@ 2017-02-11  0:38 ` Shaohua Li
  5 siblings, 0 replies; 15+ messages in thread
From: Shaohua Li @ 2017-02-11  0:38 UTC (permalink / raw)
  To: Ming Lei
  Cc: Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown

On Fri, Feb 10, 2017 at 06:56:12PM +0800, Ming Lei wrote:
> Hi,
> 
> This patches replaces bio_clone() with bio_fast_clone() in
> bio_clone_mddev() because:
> 
> 1) bio_clone_mddev() is used in raid normal I/O and isn't in
> resync I/O path, and all the direct access to bvec table in
> raid happens on resync I/O only except for write behind of raid1.
> Write behind is treated specially, so the replacement is safe.
> 
> 2) for write behind, bio_clone() is kept, but this patchset
> introduces bio_clone_bioset_partial() to just clone one specific 
> bvecs range instead of whole table. Then write behind is improved
> too.

Thanks! this patch set looks good to me.
Jens,
can you look at the first patch? If it's ok, I'll carry it in my tree.

Thanks,
Shaohua
 
> V1:
> 	1) don't introduce bio_clone_slow_mddev_partial()
> 	2) return failure if mddev->bio_set can't be created
> 	3) remove check in bio_clone_mddev() as suggested by
> 	Christoph Hellwig.
> 	4) rename bio_clone_mddev() as bio_clone_fast_mddev()
> 
> 
> Ming Lei (5):
>   block: introduce bio_clone_bioset_partial()
>   md/raid1: use bio_clone_bioset_partial() in case of write behind
>   md: fail if mddev->bio_set can't be created
>   md: remove unnecessary check on mddev
>   md: fast clone bio in bio_clone_mddev()
> 
>  block/bio.c         | 61 +++++++++++++++++++++++++++++++++++++++++------------
>  drivers/md/faulty.c |  2 +-
>  drivers/md/md.c     | 14 ++++++------
>  drivers/md/md.h     |  4 ++--
>  drivers/md/raid1.c  | 26 ++++++++++++++++-------
>  drivers/md/raid10.c | 11 +++++-----
>  drivers/md/raid5.c  |  4 ++--
>  include/linux/bio.h | 11 ++++++++--
>  8 files changed, 92 insertions(+), 41 deletions(-)
> 
> -- 
> 2.7.4
> 
> Thanks,
> Ming

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

* Re: [PATCH v1 3/5] md: fail if mddev->bio_set can't be created
  2017-02-10 10:56 ` [PATCH v1 3/5] md: fail if mddev->bio_set can't be created Ming Lei
@ 2017-02-13 13:45   ` Christoph Hellwig
  0 siblings, 0 replies; 15+ messages in thread
From: Christoph Hellwig @ 2017-02-13 13:45 UTC (permalink / raw)
  To: Ming Lei
  Cc: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

but this really needs to be patch 2 in this series.

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

* Re: [PATCH v1 1/5] block: introduce bio_clone_bioset_partial()
  2017-02-10 10:56 ` [PATCH v1 1/5] block: introduce bio_clone_bioset_partial() Ming Lei
@ 2017-02-13 13:46   ` Christoph Hellwig
  2017-02-14  1:04     ` Ming Lei
  0 siblings, 1 reply; 15+ messages in thread
From: Christoph Hellwig @ 2017-02-13 13:46 UTC (permalink / raw)
  To: Ming Lei
  Cc: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown

On Fri, Feb 10, 2017 at 06:56:13PM +0800, Ming Lei wrote:
> md still need bio clone(not the fast version) for behind write,
> and it is more efficient to use bio_clone_bioset_partial().
> 
> The idea is simple and just copy the bvecs range specified from
> parameters.

Given how few users bio_clone_bioset has I wonder if we shouldn't
simply add the two new arguments to it instead of adding another
indirection.

Otherwise looks fine:

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH v1 2/5] md/raid1: use bio_clone_bioset_partial() in case of write behind
  2017-02-10 10:56 ` [PATCH v1 2/5] md/raid1: use bio_clone_bioset_partial() in case of write behind Ming Lei
@ 2017-02-13 13:48   ` Christoph Hellwig
  0 siblings, 0 replies; 15+ messages in thread
From: Christoph Hellwig @ 2017-02-13 13:48 UTC (permalink / raw)
  To: Ming Lei
  Cc: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown

> +		struct bio *mbio = NULL;
> +		int offset;
>  		if (!r1_bio->bios[i])
>  			continue;
>  
> -		mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
> -		bio_trim(mbio, r1_bio->sector - bio->bi_iter.bi_sector,
> -			 max_sectors);
> +		offset = r1_bio->sector - bio->bi_iter.bi_sector;

I think offset should be a sector_t.

Otherwise this looks fine:

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH v1 4/5] md: remove unnecessary check on mddev
  2017-02-10 10:56 ` [PATCH v1 4/5] md: remove unnecessary check on mddev Ming Lei
@ 2017-02-13 13:49   ` Christoph Hellwig
  0 siblings, 0 replies; 15+ messages in thread
From: Christoph Hellwig @ 2017-02-13 13:49 UTC (permalink / raw)
  To: Ming Lei
  Cc: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH v1 5/5] md: fast clone bio in bio_clone_mddev()
  2017-02-10 10:56 ` [PATCH v1 5/5] md: fast clone bio in bio_clone_mddev() Ming Lei
@ 2017-02-13 13:49   ` Christoph Hellwig
  0 siblings, 0 replies; 15+ messages in thread
From: Christoph Hellwig @ 2017-02-13 13:49 UTC (permalink / raw)
  To: Ming Lei
  Cc: Shaohua Li, Jens Axboe, linux-kernel, linux-raid, linux-block,
	Christoph Hellwig, NeilBrown

Please use bio_clone_fast directly and kill the wrapper.

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

* Re: [PATCH v1 1/5] block: introduce bio_clone_bioset_partial()
  2017-02-13 13:46   ` Christoph Hellwig
@ 2017-02-14  1:04     ` Ming Lei
  2017-02-14 16:01       ` Christoph Hellwig
  0 siblings, 1 reply; 15+ messages in thread
From: Ming Lei @ 2017-02-14  1:04 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Shaohua Li, Jens Axboe, Linux Kernel Mailing List,
	open list:SOFTWARE RAID (Multiple Disks) SUPPORT, linux-block,
	NeilBrown

On Mon, Feb 13, 2017 at 9:46 PM, Christoph Hellwig <hch@infradead.org> wrote:
> On Fri, Feb 10, 2017 at 06:56:13PM +0800, Ming Lei wrote:
>> md still need bio clone(not the fast version) for behind write,
>> and it is more efficient to use bio_clone_bioset_partial().
>>
>> The idea is simple and just copy the bvecs range specified from
>> parameters.
>
> Given how few users bio_clone_bioset has I wonder if we shouldn't
> simply add the two new arguments to it instead of adding another
> indirection.

For md write-behind, looks we have to provide the two arguments,
could you explain a bit how we can do that by adding another indirection?

>
> Otherwise looks fine:
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>

Thanks!

-- 
Ming Lei

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

* Re: [PATCH v1 1/5] block: introduce bio_clone_bioset_partial()
  2017-02-14  1:04     ` Ming Lei
@ 2017-02-14 16:01       ` Christoph Hellwig
  2017-02-15  2:26         ` Ming Lei
  0 siblings, 1 reply; 15+ messages in thread
From: Christoph Hellwig @ 2017-02-14 16:01 UTC (permalink / raw)
  To: Ming Lei
  Cc: Christoph Hellwig, Shaohua Li, Jens Axboe,
	Linux Kernel Mailing List,
	open list:SOFTWARE RAID (Multiple Disks) SUPPORT, linux-block,
	NeilBrown

On Tue, Feb 14, 2017 at 09:04:26AM +0800, Ming Lei wrote:
> On Mon, Feb 13, 2017 at 9:46 PM, Christoph Hellwig <hch@infradead.org> wrote:
> > On Fri, Feb 10, 2017 at 06:56:13PM +0800, Ming Lei wrote:
> >> md still need bio clone(not the fast version) for behind write,
> >> and it is more efficient to use bio_clone_bioset_partial().
> >>
> >> The idea is simple and just copy the bvecs range specified from
> >> parameters.
> >
> > Given how few users bio_clone_bioset has I wonder if we shouldn't
> > simply add the two new arguments to it instead of adding another
> > indirection.
> 
> For md write-behind, looks we have to provide the two arguments,
> could you explain a bit how we can do that by adding another indirection?

I meant to just pass the additional arguments that 
bio_clone_bioset_partial has to bio_clone_bioset.

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

* Re: [PATCH v1 1/5] block: introduce bio_clone_bioset_partial()
  2017-02-14 16:01       ` Christoph Hellwig
@ 2017-02-15  2:26         ` Ming Lei
  0 siblings, 0 replies; 15+ messages in thread
From: Ming Lei @ 2017-02-15  2:26 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Shaohua Li, Jens Axboe, Linux Kernel Mailing List,
	open list:SOFTWARE RAID (Multiple Disks) SUPPORT, linux-block,
	NeilBrown

On Wed, Feb 15, 2017 at 12:01 AM, Christoph Hellwig <hch@infradead.org> wrote:
> On Tue, Feb 14, 2017 at 09:04:26AM +0800, Ming Lei wrote:
>> On Mon, Feb 13, 2017 at 9:46 PM, Christoph Hellwig <hch@infradead.org> wrote:
>> > On Fri, Feb 10, 2017 at 06:56:13PM +0800, Ming Lei wrote:
>> >> md still need bio clone(not the fast version) for behind write,
>> >> and it is more efficient to use bio_clone_bioset_partial().
>> >>
>> >> The idea is simple and just copy the bvecs range specified from
>> >> parameters.
>> >
>> > Given how few users bio_clone_bioset has I wonder if we shouldn't
>> > simply add the two new arguments to it instead of adding another
>> > indirection.
>>
>> For md write-behind, looks we have to provide the two arguments,
>> could you explain a bit how we can do that by adding another indirection?
>
> I meant to just pass the additional arguments that
> bio_clone_bioset_partial has to bio_clone_bioset.

That may cause more changes(fs, ...) into this patchset, so I suggest to
do that in another patchset, especially after we confirmed current
users of bio_clone is absolutely necessary, and I will check if other bio_clone
can be converted to fast clone.


Thanks,
Ming Lei

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

end of thread, other threads:[~2017-02-15  2:26 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-10 10:56 [PATCH v1 0/5] md: use bio_clone_fast() Ming Lei
2017-02-10 10:56 ` [PATCH v1 1/5] block: introduce bio_clone_bioset_partial() Ming Lei
2017-02-13 13:46   ` Christoph Hellwig
2017-02-14  1:04     ` Ming Lei
2017-02-14 16:01       ` Christoph Hellwig
2017-02-15  2:26         ` Ming Lei
2017-02-10 10:56 ` [PATCH v1 2/5] md/raid1: use bio_clone_bioset_partial() in case of write behind Ming Lei
2017-02-13 13:48   ` Christoph Hellwig
2017-02-10 10:56 ` [PATCH v1 3/5] md: fail if mddev->bio_set can't be created Ming Lei
2017-02-13 13:45   ` Christoph Hellwig
2017-02-10 10:56 ` [PATCH v1 4/5] md: remove unnecessary check on mddev Ming Lei
2017-02-13 13:49   ` Christoph Hellwig
2017-02-10 10:56 ` [PATCH v1 5/5] md: fast clone bio in bio_clone_mddev() Ming Lei
2017-02-13 13:49   ` Christoph Hellwig
2017-02-11  0:38 ` [PATCH v1 0/5] md: use bio_clone_fast() Shaohua Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).