linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* bio_add_pc_page cleanups
@ 2019-08-12 15:39 Christoph Hellwig
  2019-08-12 15:39 ` [PATCH 1/3] block: improve the gap check in __bio_add_pc_page Christoph Hellwig
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Christoph Hellwig @ 2019-08-12 15:39 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block

Hi Jens,

this series cleans up the bio_add_pc_page code and reuses more code
from the regular bio path.

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

* [PATCH 1/3] block: improve the gap check in __bio_add_pc_page
  2019-08-12 15:39 bio_add_pc_page cleanups Christoph Hellwig
@ 2019-08-12 15:39 ` Christoph Hellwig
  2019-08-12 15:39 ` [PATCH 2/3] block: create a bio_try_merge_pc_page helper Christoph Hellwig
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2019-08-12 15:39 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Johannes Thumshirn

If we can add more data into an existing segment we do not create a gap
per definition, so move the check for a gap after the attempt to merge
into the segment.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
---
 block/bio.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 24a496f5d2e2..9f80bf4531b3 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -710,18 +710,18 @@ static int __bio_add_pc_page(struct request_queue *q, struct bio *bio,
 			goto done;
 		}
 
-		/*
-		 * If the queue doesn't support SG gaps and adding this
-		 * offset would create a gap, disallow it.
-		 */
-		if (bvec_gap_to_prev(q, bvec, offset))
-			return 0;
-
 		if (page_is_mergeable(bvec, page, len, offset, &same_page) &&
 		    can_add_page_to_seg(q, bvec, page, len, offset)) {
 			bvec->bv_len += len;
 			goto done;
 		}
+
+		/*
+		 * If the queue doesn't support SG gaps and adding this segment
+		 * would create a gap, disallow it.
+		 */
+		if (bvec_gap_to_prev(q, bvec, offset))
+			return 0;
 	}
 
 	if (bio_full(bio, len))
-- 
2.20.1


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

* [PATCH 2/3] block: create a bio_try_merge_pc_page helper
  2019-08-12 15:39 bio_add_pc_page cleanups Christoph Hellwig
  2019-08-12 15:39 ` [PATCH 1/3] block: improve the gap check in __bio_add_pc_page Christoph Hellwig
@ 2019-08-12 15:39 ` Christoph Hellwig
  2019-08-12 15:39 ` [PATCH 3/3] block: move same page handling from __bio_add_pc_page to the callers Christoph Hellwig
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2019-08-12 15:39 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block

Passsthrough bio handling should be the same as normal bio handling,
except that we need to take hardware limitations into account.  Thus
use the common try_merge implementation after checking the hardware
limits.  This changes behavior in that we now also check segment
and dma boundary settings for same page merges, which is a little
more work but has no effect as those need to be larger than the
page size.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/bio.c | 34 ++++++++++------------------------
 1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 9f80bf4531b3..6ea4b9257667 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -646,25 +646,20 @@ static inline bool page_is_mergeable(const struct bio_vec *bv,
 	return true;
 }
 
-/*
- * Check if the @page can be added to the current segment(@bv), and make
- * sure to call it only if page_is_mergeable(@bv, @page) is true
- */
-static bool can_add_page_to_seg(struct request_queue *q,
-		struct bio_vec *bv, struct page *page, unsigned len,
-		unsigned offset)
+static bool bio_try_merge_pc_page(struct request_queue *q, struct bio *bio,
+		struct page *page, unsigned len, unsigned offset,
+		bool *same_page)
 {
+	struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
 	unsigned long mask = queue_segment_boundary(q);
 	phys_addr_t addr1 = page_to_phys(bv->bv_page) + bv->bv_offset;
 	phys_addr_t addr2 = page_to_phys(page) + offset + len - 1;
 
 	if ((addr1 | mask) != (addr2 | mask))
 		return false;
-
 	if (bv->bv_len + len > queue_max_segment_size(q))
 		return false;
-
-	return true;
+	return __bio_try_merge_page(bio, page, len, offset, same_page);
 }
 
 /**
@@ -700,26 +695,18 @@ static int __bio_add_pc_page(struct request_queue *q, struct bio *bio,
 		return 0;
 
 	if (bio->bi_vcnt > 0) {
-		bvec = &bio->bi_io_vec[bio->bi_vcnt - 1];
-
-		if (page == bvec->bv_page &&
-		    offset == bvec->bv_offset + bvec->bv_len) {
-			if (put_same_page)
+		if (bio_try_merge_pc_page(q, bio, page, len, offset,
+				&same_page)) {
+			if (put_same_page && same_page)
 				put_page(page);
-			bvec->bv_len += len;
-			goto done;
-		}
-
-		if (page_is_mergeable(bvec, page, len, offset, &same_page) &&
-		    can_add_page_to_seg(q, bvec, page, len, offset)) {
-			bvec->bv_len += len;
-			goto done;
+			return len;
 		}
 
 		/*
 		 * If the queue doesn't support SG gaps and adding this segment
 		 * would create a gap, disallow it.
 		 */
+		bvec = &bio->bi_io_vec[bio->bi_vcnt - 1];
 		if (bvec_gap_to_prev(q, bvec, offset))
 			return 0;
 	}
@@ -735,7 +722,6 @@ static int __bio_add_pc_page(struct request_queue *q, struct bio *bio,
 	bvec->bv_len = len;
 	bvec->bv_offset = offset;
 	bio->bi_vcnt++;
- done:
 	bio->bi_iter.bi_size += len;
 	return len;
 }
-- 
2.20.1


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

* [PATCH 3/3] block: move same page handling from __bio_add_pc_page to the callers
  2019-08-12 15:39 bio_add_pc_page cleanups Christoph Hellwig
  2019-08-12 15:39 ` [PATCH 1/3] block: improve the gap check in __bio_add_pc_page Christoph Hellwig
  2019-08-12 15:39 ` [PATCH 2/3] block: create a bio_try_merge_pc_page helper Christoph Hellwig
@ 2019-08-12 15:39 ` Christoph Hellwig
  2019-08-22  1:00 ` bio_add_pc_page cleanups Christoph Hellwig
  2019-08-22 13:15 ` Jens Axboe
  4 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2019-08-12 15:39 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block

Hiding page refcount manipulation inside a low-level bio helper is
somewhat awkward.  Instead return the same page information to the
callers, where it fits in much better.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/bio.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 6ea4b9257667..11aa6738ed62 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -669,7 +669,7 @@ static bool bio_try_merge_pc_page(struct request_queue *q, struct bio *bio,
  *	@page: page to add
  *	@len: vec entry length
  *	@offset: vec entry offset
- *	@put_same_page: put the page if it is same with last added page
+ *	@same_page: return if the merge happen inside the same page
  *
  *	Attempt to add a page to the bio_vec maplist. This can fail for a
  *	number of reasons, such as the bio being full or target block device
@@ -680,10 +680,9 @@ static bool bio_try_merge_pc_page(struct request_queue *q, struct bio *bio,
  */
 static int __bio_add_pc_page(struct request_queue *q, struct bio *bio,
 		struct page *page, unsigned int len, unsigned int offset,
-		bool put_same_page)
+		bool *same_page)
 {
 	struct bio_vec *bvec;
-	bool same_page = false;
 
 	/*
 	 * cloned bio must not modify vec list
@@ -695,12 +694,8 @@ static int __bio_add_pc_page(struct request_queue *q, struct bio *bio,
 		return 0;
 
 	if (bio->bi_vcnt > 0) {
-		if (bio_try_merge_pc_page(q, bio, page, len, offset,
-				&same_page)) {
-			if (put_same_page && same_page)
-				put_page(page);
+		if (bio_try_merge_pc_page(q, bio, page, len, offset, same_page))
 			return len;
-		}
 
 		/*
 		 * If the queue doesn't support SG gaps and adding this segment
@@ -729,7 +724,8 @@ static int __bio_add_pc_page(struct request_queue *q, struct bio *bio,
 int bio_add_pc_page(struct request_queue *q, struct bio *bio,
 		struct page *page, unsigned int len, unsigned int offset)
 {
-	return __bio_add_pc_page(q, bio, page, len, offset, false);
+	bool same_page = false;
+	return __bio_add_pc_page(q, bio, page, len, offset, &same_page);
 }
 EXPORT_SYMBOL(bio_add_pc_page);
 
@@ -1370,13 +1366,17 @@ struct bio *bio_map_user_iov(struct request_queue *q,
 			for (j = 0; j < npages; j++) {
 				struct page *page = pages[j];
 				unsigned int n = PAGE_SIZE - offs;
+				bool same_page = false;
 
 				if (n > bytes)
 					n = bytes;
 
 				if (!__bio_add_pc_page(q, bio, page, n, offs,
-							true))
+						&same_page)) {
+					if (same_page)
+						put_page(page);
 					break;
+				}
 
 				added += n;
 				bytes -= n;
-- 
2.20.1


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

* Re: bio_add_pc_page cleanups
  2019-08-12 15:39 bio_add_pc_page cleanups Christoph Hellwig
                   ` (2 preceding siblings ...)
  2019-08-12 15:39 ` [PATCH 3/3] block: move same page handling from __bio_add_pc_page to the callers Christoph Hellwig
@ 2019-08-22  1:00 ` Christoph Hellwig
  2019-08-22 13:15 ` Jens Axboe
  4 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2019-08-22  1:00 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block

On Mon, Aug 12, 2019 at 05:39:55PM +0200, Christoph Hellwig wrote:
> Hi Jens,
> 
> this series cleans up the bio_add_pc_page code and reuses more code
> from the regular bio path.

ping?

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

* Re: bio_add_pc_page cleanups
  2019-08-12 15:39 bio_add_pc_page cleanups Christoph Hellwig
                   ` (3 preceding siblings ...)
  2019-08-22  1:00 ` bio_add_pc_page cleanups Christoph Hellwig
@ 2019-08-22 13:15 ` Jens Axboe
  4 siblings, 0 replies; 10+ messages in thread
From: Jens Axboe @ 2019-08-22 13:15 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-block

On 8/12/19 9:39 AM, Christoph Hellwig wrote:
> Hi Jens,
> 
> this series cleans up the bio_add_pc_page code and reuses more code
> from the regular bio path.

LGTM, applied for 5.4, thanks.

-- 
Jens Axboe


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

* bio_add_pc_page cleanups
@ 2019-07-03 13:00 Christoph Hellwig
  0 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2019-07-03 13:00 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block

Hi Jens,

this series cleans up the bio_add_pc_page code and reuses more code
from the regular bio path.

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

* Re: bio_add_pc_page cleanups
  2019-04-25  7:04 Christoph Hellwig
  2019-04-30 15:05 ` Christoph Hellwig
@ 2019-04-30 15:27 ` Jens Axboe
  1 sibling, 0 replies; 10+ messages in thread
From: Jens Axboe @ 2019-04-30 15:27 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-block

On 4/25/19 1:04 AM, Christoph Hellwig wrote:
> Hi Jens,
> 
> please take a look at these trivial bio_add_pc_page cleanups.

LGTM, applied.

-- 
Jens Axboe


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

* Re: bio_add_pc_page cleanups
  2019-04-25  7:04 Christoph Hellwig
@ 2019-04-30 15:05 ` Christoph Hellwig
  2019-04-30 15:27 ` Jens Axboe
  1 sibling, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2019-04-30 15:05 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block

ping?

On Thu, Apr 25, 2019 at 09:04:32AM +0200, Christoph Hellwig wrote:
> Hi Jens,
> 
> please take a look at these trivial bio_add_pc_page cleanups.
---end quoted text---

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

* bio_add_pc_page cleanups
@ 2019-04-25  7:04 Christoph Hellwig
  2019-04-30 15:05 ` Christoph Hellwig
  2019-04-30 15:27 ` Jens Axboe
  0 siblings, 2 replies; 10+ messages in thread
From: Christoph Hellwig @ 2019-04-25  7:04 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block

Hi Jens,

please take a look at these trivial bio_add_pc_page cleanups.

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

end of thread, other threads:[~2019-08-22 13:15 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-12 15:39 bio_add_pc_page cleanups Christoph Hellwig
2019-08-12 15:39 ` [PATCH 1/3] block: improve the gap check in __bio_add_pc_page Christoph Hellwig
2019-08-12 15:39 ` [PATCH 2/3] block: create a bio_try_merge_pc_page helper Christoph Hellwig
2019-08-12 15:39 ` [PATCH 3/3] block: move same page handling from __bio_add_pc_page to the callers Christoph Hellwig
2019-08-22  1:00 ` bio_add_pc_page cleanups Christoph Hellwig
2019-08-22 13:15 ` Jens Axboe
  -- strict thread matches above, loose matches on Subject: below --
2019-07-03 13:00 Christoph Hellwig
2019-04-25  7:04 Christoph Hellwig
2019-04-30 15:05 ` Christoph Hellwig
2019-04-30 15:27 ` Jens Axboe

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).