* rationalize the flow in bio_add_page and friends
@ 2023-05-12 13:38 Christoph Hellwig
2023-05-12 13:38 ` [PATCH 1/8] block: tidy up the bio full checks in bio_add_hw_page Christoph Hellwig
` (9 more replies)
0 siblings, 10 replies; 24+ messages in thread
From: Christoph Hellwig @ 2023-05-12 13:38 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jinyoung Choi, linux-block
Hi Jens,
when reviewing v2 of Jinyoung's "Change the integrity configuration
method in block" series I noticed that someone made a complete mess of
the bio_add_page flow, so this untangles this to make the code better
reusable for adding integrity payloads. (I'll also have a word with
younger me when I get the chance about this..)
Diffstat:
bio.c | 123 ++++++++++++++++++++++++++++--------------------------------------
1 file changed, 53 insertions(+), 70 deletions(-)
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/8] block: tidy up the bio full checks in bio_add_hw_page
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
@ 2023-05-12 13:38 ` Christoph Hellwig
2023-05-17 7:18 ` Jinyoung CHOI
2023-05-12 13:38 ` [PATCH 2/8] block: use SECTOR_SHIFT bio_add_hw_page Christoph Hellwig
` (8 subsequent siblings)
9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2023-05-12 13:38 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jinyoung Choi, linux-block
bio_add_hw_page already checks if the number of bytes trying to be added
even fit into max_hw_sectors limit of the queue. Remove the call to
bio_full and just do a check for the smaller of the number of segments
in the bio and the queue max segments limit, and do this cheap check
before the more expensive gap to previous check.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 043944fd46ebbc..1528ca0f3df6dc 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1014,6 +1014,10 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
if (bio_try_merge_hw_seg(q, bio, page, len, offset, same_page))
return len;
+ if (bio->bi_vcnt >=
+ min(bio->bi_max_vecs, queue_max_segments(q)))
+ return 0;
+
/*
* If the queue doesn't support SG gaps and adding this segment
* would create a gap, disallow it.
@@ -1023,12 +1027,6 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
return 0;
}
- if (bio_full(bio, len))
- return 0;
-
- if (bio->bi_vcnt >= queue_max_segments(q))
- return 0;
-
bvec_set_page(&bio->bi_io_vec[bio->bi_vcnt], page, len, offset);
bio->bi_vcnt++;
bio->bi_iter.bi_size += len;
--
2.39.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 2/8] block: use SECTOR_SHIFT bio_add_hw_page
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
2023-05-12 13:38 ` [PATCH 1/8] block: tidy up the bio full checks in bio_add_hw_page Christoph Hellwig
@ 2023-05-12 13:38 ` Christoph Hellwig
2023-05-16 12:00 ` Johannes Thumshirn
2023-05-19 6:05 ` Jinyoung CHOI
2023-05-12 13:38 ` [PATCH 3/8] block: move the BIO_CLONED checks out of __bio_try_merge_page Christoph Hellwig
` (7 subsequent siblings)
9 siblings, 2 replies; 24+ messages in thread
From: Christoph Hellwig @ 2023-05-12 13:38 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jinyoung Choi, linux-block
Use the SECTOR_SHIFT magic constant instead of the magic number.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/bio.c b/block/bio.c
index 1528ca0f3df6dc..d020065e613cc8 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1007,7 +1007,7 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
return 0;
- if (((bio->bi_iter.bi_size + len) >> 9) > max_sectors)
+ if (((bio->bi_iter.bi_size + len) >> SECTOR_SHIFT) > max_sectors)
return 0;
if (bio->bi_vcnt > 0) {
--
2.39.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 3/8] block: move the BIO_CLONED checks out of __bio_try_merge_page
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
2023-05-12 13:38 ` [PATCH 1/8] block: tidy up the bio full checks in bio_add_hw_page Christoph Hellwig
2023-05-12 13:38 ` [PATCH 2/8] block: use SECTOR_SHIFT bio_add_hw_page Christoph Hellwig
@ 2023-05-12 13:38 ` Christoph Hellwig
2023-05-16 12:01 ` Johannes Thumshirn
2023-05-19 6:08 ` Jinyoung CHOI
2023-05-12 13:38 ` [PATCH 4/8] block: move the bi_vcnt check " Christoph Hellwig
` (6 subsequent siblings)
9 siblings, 2 replies; 24+ messages in thread
From: Christoph Hellwig @ 2023-05-12 13:38 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jinyoung Choi, linux-block
__bio_try_merge_page is a way too low-level helper to assert that the
bio is not cloned. Move the check into bio_add_page and
bio_iov_iter_get_pages instead, which are the high level entry points
that should enforce this variant. bio_add_hw_page already this
check, coverig the third (indirect) caller of __bio_try_merge_page.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index d020065e613cc8..c7bf20a779ebed 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -945,9 +945,6 @@ static inline bool page_is_mergeable(const struct bio_vec *bv,
static bool __bio_try_merge_page(struct bio *bio, struct page *page,
unsigned int len, unsigned int off, bool *same_page)
{
- if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
- return false;
-
if (bio->bi_vcnt > 0) {
struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
@@ -1127,6 +1124,9 @@ int bio_add_page(struct bio *bio, struct page *page,
{
bool same_page = false;
+ if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
+ return 0;
+
if (!__bio_try_merge_page(bio, page, len, offset, &same_page)) {
if (bio_full(bio, len))
return 0;
@@ -1328,6 +1328,9 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
{
int ret = 0;
+ if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
+ return -EIO;
+
if (iov_iter_is_bvec(iter)) {
bio_iov_bvec_set(bio, iter);
iov_iter_advance(iter, bio->bi_iter.bi_size);
--
2.39.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 4/8] block: move the bi_vcnt check out of __bio_try_merge_page
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
` (2 preceding siblings ...)
2023-05-12 13:38 ` [PATCH 3/8] block: move the BIO_CLONED checks out of __bio_try_merge_page Christoph Hellwig
@ 2023-05-12 13:38 ` Christoph Hellwig
2023-05-16 12:04 ` Johannes Thumshirn
2023-05-19 6:13 ` Jinyoung CHOI
2023-05-12 13:38 ` [PATCH 5/8] block: move the bi_size overflow check in __bio_try_merge_page Christoph Hellwig
` (5 subsequent siblings)
9 siblings, 2 replies; 24+ messages in thread
From: Christoph Hellwig @ 2023-05-12 13:38 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jinyoung Choi, linux-block
Move the bi_vcnt out of __bio_try_merge_page and into the two callers
that don't already have it in preparation for additional changes to
__bio_try_merge_page.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio.c | 44 ++++++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index c7bf20a779ebed..5d2c95e05b1a52 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -945,20 +945,17 @@ static inline bool page_is_mergeable(const struct bio_vec *bv,
static bool __bio_try_merge_page(struct bio *bio, struct page *page,
unsigned int len, unsigned int off, bool *same_page)
{
- if (bio->bi_vcnt > 0) {
- struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
-
- if (page_is_mergeable(bv, page, len, off, same_page)) {
- if (bio->bi_iter.bi_size > UINT_MAX - len) {
- *same_page = false;
- return false;
- }
- bv->bv_len += len;
- bio->bi_iter.bi_size += len;
- return true;
- }
+ struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
+
+ if (!page_is_mergeable(bv, page, len, off, same_page))
+ return false;
+ if (bio->bi_iter.bi_size > UINT_MAX - len) {
+ *same_page = false;
+ return false;
}
- return false;
+ bv->bv_len += len;
+ bio->bi_iter.bi_size += len;
+ return true;
}
/*
@@ -1127,11 +1124,13 @@ int bio_add_page(struct bio *bio, struct page *page,
if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
return 0;
- if (!__bio_try_merge_page(bio, page, len, offset, &same_page)) {
- if (bio_full(bio, len))
- return 0;
- __bio_add_page(bio, page, len, offset);
- }
+ if (bio->bi_vcnt > 0 &&
+ __bio_try_merge_page(bio, page, len, offset, &same_page))
+ return len;
+
+ if (bio_full(bio, len))
+ return 0;
+ __bio_add_page(bio, page, len, offset);
return len;
}
EXPORT_SYMBOL(bio_add_page);
@@ -1198,13 +1197,14 @@ static int bio_iov_add_page(struct bio *bio, struct page *page,
{
bool same_page = false;
- if (!__bio_try_merge_page(bio, page, len, offset, &same_page)) {
- __bio_add_page(bio, page, len, offset);
+ if (bio->bi_vcnt > 0 &&
+ __bio_try_merge_page(bio, page, len, offset, &same_page)) {
+ if (same_page)
+ put_page(page);
return 0;
}
- if (same_page)
- put_page(page);
+ __bio_add_page(bio, page, len, offset);
return 0;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 5/8] block: move the bi_size overflow check in __bio_try_merge_page
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
` (3 preceding siblings ...)
2023-05-12 13:38 ` [PATCH 4/8] block: move the bi_vcnt check " Christoph Hellwig
@ 2023-05-12 13:38 ` Christoph Hellwig
2023-05-16 12:08 ` Johannes Thumshirn
2023-05-19 6:14 ` Jinyoung CHOI
2023-05-12 13:38 ` [PATCH 6/8] block: downgrade a bio_full call in bio_add_page Christoph Hellwig
` (4 subsequent siblings)
9 siblings, 2 replies; 24+ messages in thread
From: Christoph Hellwig @ 2023-05-12 13:38 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jinyoung Choi, linux-block
Checking for availability in bi_size in a function that attempts to
merge into an existing segment is a bit odd, as the limit also applies
when adding a new segment. This code works fine as we always call
__bio_try_merge_page, but contributes to sub-optimal calling conventions
and doesn't lead to clear code.
Move it to two of the callers instead, the third one already has a more
strict check that includes max_hw_segments anyway.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 5d2c95e05b1a52..93e6bca3c2239f 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -949,10 +949,6 @@ static bool __bio_try_merge_page(struct bio *bio, struct page *page,
if (!page_is_mergeable(bv, page, len, off, same_page))
return false;
- if (bio->bi_iter.bi_size > UINT_MAX - len) {
- *same_page = false;
- return false;
- }
bv->bv_len += len;
bio->bi_iter.bi_size += len;
return true;
@@ -1123,6 +1119,8 @@ int bio_add_page(struct bio *bio, struct page *page,
if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
return 0;
+ if (bio->bi_iter.bi_size > UINT_MAX - len)
+ return 0;
if (bio->bi_vcnt > 0 &&
__bio_try_merge_page(bio, page, len, offset, &same_page))
@@ -1197,6 +1195,9 @@ static int bio_iov_add_page(struct bio *bio, struct page *page,
{
bool same_page = false;
+ if (WARN_ON_ONCE(bio->bi_iter.bi_size > UINT_MAX - len))
+ return -EIO;
+
if (bio->bi_vcnt > 0 &&
__bio_try_merge_page(bio, page, len, offset, &same_page)) {
if (same_page)
--
2.39.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 6/8] block: downgrade a bio_full call in bio_add_page
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
` (4 preceding siblings ...)
2023-05-12 13:38 ` [PATCH 5/8] block: move the bi_size overflow check in __bio_try_merge_page Christoph Hellwig
@ 2023-05-12 13:38 ` Christoph Hellwig
2023-05-19 6:18 ` Jinyoung CHOI
2023-05-12 13:39 ` [PATCH 7/8] block: move the bi_size update out of __bio_try_merge_page Christoph Hellwig
` (3 subsequent siblings)
9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2023-05-12 13:38 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jinyoung Choi, linux-block
bio_add_page already checks that there is space in bi_size a little
earlier. So after we failed to add to an existing segment, just check
that there is another one available instead of duplicating the bi_size
check.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/bio.c b/block/bio.c
index 93e6bca3c2239f..89b1475de0c370 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1126,7 +1126,7 @@ int bio_add_page(struct bio *bio, struct page *page,
__bio_try_merge_page(bio, page, len, offset, &same_page))
return len;
- if (bio_full(bio, len))
+ if (bio->bi_vcnt >= bio->bi_max_vecs)
return 0;
__bio_add_page(bio, page, len, offset);
return len;
--
2.39.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 7/8] block: move the bi_size update out of __bio_try_merge_page
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
` (5 preceding siblings ...)
2023-05-12 13:38 ` [PATCH 6/8] block: downgrade a bio_full call in bio_add_page Christoph Hellwig
@ 2023-05-12 13:39 ` Christoph Hellwig
2023-05-19 6:27 ` Jinyoung CHOI
2023-05-12 13:39 ` [PATCH 8/8] block: don't pass a bio to bio_try_merge_hw_seg Christoph Hellwig
` (2 subsequent siblings)
9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2023-05-12 13:39 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jinyoung Choi, linux-block
The update of bi_size is the only thing in __bio_try_merge_page that
needs a bio. Move it to the callers, and merge __bio_try_merge_page
and page_is_mergeable into a single bvec_try_merge_page that only takes
the current bvec instead of a full bio. This will allow reusing this
function for supporting multi-page integrity payload bvecs.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio.c | 57 +++++++++++++++++++----------------------------------
1 file changed, 20 insertions(+), 37 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 89b1475de0c370..106009707ca1c5 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -903,9 +903,8 @@ static inline bool bio_full(struct bio *bio, unsigned len)
return false;
}
-static inline bool page_is_mergeable(const struct bio_vec *bv,
- struct page *page, unsigned int len, unsigned int off,
- bool *same_page)
+static bool bvec_try_merge_page(struct bio_vec *bv, struct page *page,
+ unsigned int len, unsigned int off, bool *same_page)
{
size_t bv_end = bv->bv_offset + bv->bv_len;
phys_addr_t vec_end_addr = page_to_phys(bv->bv_page) + bv_end - 1;
@@ -919,38 +918,14 @@ static inline bool page_is_mergeable(const struct bio_vec *bv,
return false;
*same_page = ((vec_end_addr & PAGE_MASK) == page_addr);
- if (*same_page)
- return true;
- else if (IS_ENABLED(CONFIG_KMSAN))
- return false;
- return (bv->bv_page + bv_end / PAGE_SIZE) == (page + off / PAGE_SIZE);
-}
-
-/**
- * __bio_try_merge_page - try appending data to an existing bvec.
- * @bio: destination bio
- * @page: start page to add
- * @len: length of the data to add
- * @off: offset of the data relative to @page
- * @same_page: return if the segment has been merged inside the same page
- *
- * Try to add the data at @page + @off to the last bvec of @bio. This is a
- * useful optimisation for file systems with a block size smaller than the
- * page size.
- *
- * Warn if (@len, @off) crosses pages in case that @same_page is true.
- *
- * Return %true on success or %false on failure.
- */
-static bool __bio_try_merge_page(struct bio *bio, struct page *page,
- unsigned int len, unsigned int off, bool *same_page)
-{
- struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
+ if (!*same_page) {
+ if (IS_ENABLED(CONFIG_KMSAN))
+ return false;
+ if (bv->bv_page + bv_end / PAGE_SIZE != page + off / PAGE_SIZE)
+ return false;
+ }
- if (!page_is_mergeable(bv, page, len, off, same_page))
- return false;
bv->bv_len += len;
- bio->bi_iter.bi_size += len;
return true;
}
@@ -972,7 +947,7 @@ static bool bio_try_merge_hw_seg(struct request_queue *q, struct bio *bio,
return false;
if (bv->bv_len + len > queue_max_segment_size(q))
return false;
- return __bio_try_merge_page(bio, page, len, offset, same_page);
+ return bvec_try_merge_page(bv, page, len, offset, same_page);
}
/**
@@ -1001,8 +976,11 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
return 0;
if (bio->bi_vcnt > 0) {
- if (bio_try_merge_hw_seg(q, bio, page, len, offset, same_page))
+ if (bio_try_merge_hw_seg(q, bio, page, len, offset,
+ same_page)) {
+ bio->bi_iter.bi_size += len;
return len;
+ }
if (bio->bi_vcnt >=
min(bio->bi_max_vecs, queue_max_segments(q)))
@@ -1123,8 +1101,11 @@ int bio_add_page(struct bio *bio, struct page *page,
return 0;
if (bio->bi_vcnt > 0 &&
- __bio_try_merge_page(bio, page, len, offset, &same_page))
+ bvec_try_merge_page(&bio->bi_io_vec[bio->bi_vcnt - 1],
+ page, len, offset, &same_page)) {
+ bio->bi_iter.bi_size += len;
return len;
+ }
if (bio->bi_vcnt >= bio->bi_max_vecs)
return 0;
@@ -1199,7 +1180,9 @@ static int bio_iov_add_page(struct bio *bio, struct page *page,
return -EIO;
if (bio->bi_vcnt > 0 &&
- __bio_try_merge_page(bio, page, len, offset, &same_page)) {
+ bvec_try_merge_page(&bio->bi_io_vec[bio->bi_vcnt - 1],
+ page, len, offset, &same_page)) {
+ bio->bi_iter.bi_size += len;
if (same_page)
put_page(page);
return 0;
--
2.39.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 8/8] block: don't pass a bio to bio_try_merge_hw_seg
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
` (6 preceding siblings ...)
2023-05-12 13:39 ` [PATCH 7/8] block: move the bi_size update out of __bio_try_merge_page Christoph Hellwig
@ 2023-05-12 13:39 ` Christoph Hellwig
2023-05-19 6:30 ` Jinyoung CHOI
2023-05-19 2:27 ` rationalize the flow in bio_add_page and friends Jens Axboe
2023-05-20 1:49 ` Jens Axboe
9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2023-05-12 13:39 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jinyoung Choi, linux-block
There is no good reason to pass the bio to bio_try_merge_hw_seg. Just
pass the current bvec and rename the function to bvec_try_merge_hw_page.
This will allow reusing this function for supporting multi-page integrity
payload bvecs.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 106009707ca1c5..79e8aa600ddbe2 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -934,11 +934,10 @@ static bool bvec_try_merge_page(struct bio_vec *bv, struct page *page,
* size limit. This is not for normal read/write bios, but for passthrough
* or Zone Append operations that we can't split.
*/
-static bool bio_try_merge_hw_seg(struct request_queue *q, struct bio *bio,
- struct page *page, unsigned len,
- unsigned offset, bool *same_page)
+static bool bvec_try_merge_hw_page(struct request_queue *q, struct bio_vec *bv,
+ 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;
@@ -967,8 +966,6 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
struct page *page, unsigned int len, unsigned int offset,
unsigned int max_sectors, bool *same_page)
{
- struct bio_vec *bvec;
-
if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
return 0;
@@ -976,7 +973,9 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
return 0;
if (bio->bi_vcnt > 0) {
- if (bio_try_merge_hw_seg(q, bio, page, len, offset,
+ struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
+
+ if (bvec_try_merge_hw_page(q, bv, page, len, offset,
same_page)) {
bio->bi_iter.bi_size += len;
return len;
@@ -990,8 +989,7 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
* 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->limits, bvec, offset))
+ if (bvec_gap_to_prev(&q->limits, bv, offset))
return 0;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 2/8] block: use SECTOR_SHIFT bio_add_hw_page
2023-05-12 13:38 ` [PATCH 2/8] block: use SECTOR_SHIFT bio_add_hw_page Christoph Hellwig
@ 2023-05-16 12:00 ` Johannes Thumshirn
2023-05-19 6:05 ` Jinyoung CHOI
1 sibling, 0 replies; 24+ messages in thread
From: Johannes Thumshirn @ 2023-05-16 12:00 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: Jinyoung Choi, linux-block@vger.kernel.org
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 3/8] block: move the BIO_CLONED checks out of __bio_try_merge_page
2023-05-12 13:38 ` [PATCH 3/8] block: move the BIO_CLONED checks out of __bio_try_merge_page Christoph Hellwig
@ 2023-05-16 12:01 ` Johannes Thumshirn
2023-05-19 6:08 ` Jinyoung CHOI
1 sibling, 0 replies; 24+ messages in thread
From: Johannes Thumshirn @ 2023-05-16 12:01 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: Jinyoung Choi, linux-block@vger.kernel.org
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 4/8] block: move the bi_vcnt check out of __bio_try_merge_page
2023-05-12 13:38 ` [PATCH 4/8] block: move the bi_vcnt check " Christoph Hellwig
@ 2023-05-16 12:04 ` Johannes Thumshirn
2023-05-19 6:13 ` Jinyoung CHOI
1 sibling, 0 replies; 24+ messages in thread
From: Johannes Thumshirn @ 2023-05-16 12:04 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: Jinyoung Choi, linux-block@vger.kernel.org
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 5/8] block: move the bi_size overflow check in __bio_try_merge_page
2023-05-12 13:38 ` [PATCH 5/8] block: move the bi_size overflow check in __bio_try_merge_page Christoph Hellwig
@ 2023-05-16 12:08 ` Johannes Thumshirn
2023-05-19 6:14 ` Jinyoung CHOI
1 sibling, 0 replies; 24+ messages in thread
From: Johannes Thumshirn @ 2023-05-16 12:08 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: Jinyoung Choi, linux-block@vger.kernel.org
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH 1/8] block: tidy up the bio full checks in bio_add_hw_page
2023-05-12 13:38 ` [PATCH 1/8] block: tidy up the bio full checks in bio_add_hw_page Christoph Hellwig
@ 2023-05-17 7:18 ` Jinyoung CHOI
0 siblings, 0 replies; 24+ messages in thread
From: Jinyoung CHOI @ 2023-05-17 7:18 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: linux-block@vger.kernel.org
Hi, Christoph.
>@@ -1014,6 +1014,10 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
> if (bio_try_merge_hw_seg(q, bio, page, len, offset, same_page))
> return len;
>
>+ if (bio->bi_vcnt >=
>+ min(bio->bi_max_vecs, queue_max_segments(q)))
>+ return 0;
>+
> /*
> * If the queue doesn't support SG gaps and adding this segment
> * would create a gap, disallow it.
>@@ -1023,12 +1027,6 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
> return 0;
> }
>
>- if (bio_full(bio, len))
>- return 0;
>-
>- if (bio->bi_vcnt >= queue_max_segments(q))
>- return 0;
>-
> bvec_set_page(&bio->bi_io_vec[bio->bi_vcnt], page, len, offset);
> bio->bi_vcnt++;
> bio->bi_iter.bi_size += len;
>--
>2.39.2
If the wrong bi_max_vecs is set in bio_init(e.g. bi_max_vec = 0),
I think we need a code to defend against page_add.
If modified in this way, it may be added to bvec normally and
cause inconsistency in the information of bio.
Best Regards,
Jinyoung.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: rationalize the flow in bio_add_page and friends
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
` (7 preceding siblings ...)
2023-05-12 13:39 ` [PATCH 8/8] block: don't pass a bio to bio_try_merge_hw_seg Christoph Hellwig
@ 2023-05-19 2:27 ` Jens Axboe
2023-05-20 1:49 ` Jens Axboe
9 siblings, 0 replies; 24+ messages in thread
From: Jens Axboe @ 2023-05-19 2:27 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Jinyoung Choi, linux-block
On 5/12/23 7:38 AM, Christoph Hellwig wrote:
> Hi Jens,
>
> when reviewing v2 of Jinyoung's "Change the integrity configuration
> method in block" series I noticed that someone made a complete mess of
> the bio_add_page flow, so this untangles this to make the code better
> reusable for adding integrity payloads. (I'll also have a word with
> younger me when I get the chance about this..)
>
> Diffstat:
> bio.c | 123 ++++++++++++++++++++++++++++--------------------------------------
> 1 file changed, 53 insertions(+), 70 deletions(-)
Nice cleanups and generated code reduction too.
--
Jens Axboe
^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH 2/8] block: use SECTOR_SHIFT bio_add_hw_page
2023-05-12 13:38 ` [PATCH 2/8] block: use SECTOR_SHIFT bio_add_hw_page Christoph Hellwig
2023-05-16 12:00 ` Johannes Thumshirn
@ 2023-05-19 6:05 ` Jinyoung CHOI
1 sibling, 0 replies; 24+ messages in thread
From: Jinyoung CHOI @ 2023-05-19 6:05 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: linux-block@vger.kernel.org
Looks good to me,
Reviewed-by: Jinyoung Choi <j-young.choi@samsung.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH 3/8] block: move the BIO_CLONED checks out of __bio_try_merge_page
2023-05-12 13:38 ` [PATCH 3/8] block: move the BIO_CLONED checks out of __bio_try_merge_page Christoph Hellwig
2023-05-16 12:01 ` Johannes Thumshirn
@ 2023-05-19 6:08 ` Jinyoung CHOI
1 sibling, 0 replies; 24+ messages in thread
From: Jinyoung CHOI @ 2023-05-19 6:08 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: linux-block@vger.kernel.org
Looks good to me,
Reviewed-by: Jinyoung Choi <j-young.choi@samsung.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH 4/8] block: move the bi_vcnt check out of __bio_try_merge_page
2023-05-12 13:38 ` [PATCH 4/8] block: move the bi_vcnt check " Christoph Hellwig
2023-05-16 12:04 ` Johannes Thumshirn
@ 2023-05-19 6:13 ` Jinyoung CHOI
1 sibling, 0 replies; 24+ messages in thread
From: Jinyoung CHOI @ 2023-05-19 6:13 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: linux-block@vger.kernel.org
Looks good to me,
Reviewed-by: Jinyoung Choi <j-young.choi@samsung.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH 5/8] block: move the bi_size overflow check in __bio_try_merge_page
2023-05-12 13:38 ` [PATCH 5/8] block: move the bi_size overflow check in __bio_try_merge_page Christoph Hellwig
2023-05-16 12:08 ` Johannes Thumshirn
@ 2023-05-19 6:14 ` Jinyoung CHOI
1 sibling, 0 replies; 24+ messages in thread
From: Jinyoung CHOI @ 2023-05-19 6:14 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: linux-block@vger.kernel.org
Looks good to me,
Reviewed-by: Jinyoung Choi <j-young.choi@samsung.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH 6/8] block: downgrade a bio_full call in bio_add_page
2023-05-12 13:38 ` [PATCH 6/8] block: downgrade a bio_full call in bio_add_page Christoph Hellwig
@ 2023-05-19 6:18 ` Jinyoung CHOI
0 siblings, 0 replies; 24+ messages in thread
From: Jinyoung CHOI @ 2023-05-19 6:18 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: linux-block@vger.kernel.org
Looks good to me,
Reviewed-by: Jinyoung Choi <j-young.choi@samsung.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH 7/8] block: move the bi_size update out of __bio_try_merge_page
2023-05-12 13:39 ` [PATCH 7/8] block: move the bi_size update out of __bio_try_merge_page Christoph Hellwig
@ 2023-05-19 6:27 ` Jinyoung CHOI
0 siblings, 0 replies; 24+ messages in thread
From: Jinyoung CHOI @ 2023-05-19 6:27 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: linux-block@vger.kernel.org
Looks good to me,
Reviewed-by: Jinyoung Choi <j-young.choi@samsung.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* RE: [PATCH 8/8] block: don't pass a bio to bio_try_merge_hw_seg
2023-05-12 13:39 ` [PATCH 8/8] block: don't pass a bio to bio_try_merge_hw_seg Christoph Hellwig
@ 2023-05-19 6:30 ` Jinyoung CHOI
0 siblings, 0 replies; 24+ messages in thread
From: Jinyoung CHOI @ 2023-05-19 6:30 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe; +Cc: linux-block@vger.kernel.org
>@@ -934,11 +934,10 @@ static bool bvec_try_merge_page(struct bio_vec *bv, struct page *page,
> * size limit. This is not for normal read/write bios, but for passthrough
> * or Zone Append operations that we can't split.
> */
>-static bool bio_try_merge_hw_seg(struct request_queue *q, struct bio *bio,
>- struct page *page, unsigned len,
>- unsigned offset, bool *same_page)
>+static bool bvec_try_merge_hw_page(struct request_queue *q, struct bio_vec *bv,
>+ struct page *page, unsigned len, unsigned offset,
>+ bool *same_page)
> {
There is a static because there is no external call based on the current change point.
So, I will modify it when using this function later.
Thank you for organizing the functions that can be used for common use.
Looks good to me,
Reviewed-by: Jinyoung Choi <j-young.choi@samsung.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: rationalize the flow in bio_add_page and friends
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
` (8 preceding siblings ...)
2023-05-19 2:27 ` rationalize the flow in bio_add_page and friends Jens Axboe
@ 2023-05-20 1:49 ` Jens Axboe
9 siblings, 0 replies; 24+ messages in thread
From: Jens Axboe @ 2023-05-20 1:49 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Jinyoung Choi, linux-block
On Fri, 12 May 2023 06:38:53 -0700, Christoph Hellwig wrote:
> when reviewing v2 of Jinyoung's "Change the integrity configuration
> method in block" series I noticed that someone made a complete mess of
> the bio_add_page flow, so this untangles this to make the code better
> reusable for adding integrity payloads. (I'll also have a word with
> younger me when I get the chance about this..)
>
> Diffstat:
> bio.c | 123 ++++++++++++++++++++++++++++--------------------------------------
> 1 file changed, 53 insertions(+), 70 deletions(-)
>
> [...]
Applied, thanks!
[1/8] block: tidy up the bio full checks in bio_add_hw_page
(no commit info)
[2/8] block: use SECTOR_SHIFT bio_add_hw_page
(no commit info)
[3/8] block: move the BIO_CLONED checks out of __bio_try_merge_page
(no commit info)
[4/8] block: move the bi_vcnt check out of __bio_try_merge_page
(no commit info)
[5/8] block: move the bi_size overflow check in __bio_try_merge_page
(no commit info)
[6/8] block: downgrade a bio_full call in bio_add_page
(no commit info)
[7/8] block: move the bi_size update out of __bio_try_merge_page
(no commit info)
[8/8] block: don't pass a bio to bio_try_merge_hw_seg
(no commit info)
Best regards,
--
Jens Axboe
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 7/8] block: move the bi_size update out of __bio_try_merge_page
2023-07-24 16:54 rationalize the flow in bio_add_page and friends v2 Christoph Hellwig
@ 2023-07-24 16:54 ` Christoph Hellwig
0 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2023-07-24 16:54 UTC (permalink / raw)
To: Jens Axboe; +Cc: Jinyoung Choi, linux-block
The update of bi_size is the only thing in __bio_try_merge_page that
needs a bio. Move it to the callers, and merge __bio_try_merge_page
and page_is_mergeable into a single bvec_try_merge_page that only takes
the current bvec instead of a full bio. This will allow reusing this
function for supporting multi-page integrity payload bvecs.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jinyoung Choi <j-young.choi@samsung.com>
---
block/bio.c | 57 +++++++++++++++++++----------------------------------
1 file changed, 20 insertions(+), 37 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index d8e0e8de8cf4f6..23b7a001b5005d 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -903,9 +903,8 @@ static inline bool bio_full(struct bio *bio, unsigned len)
return false;
}
-static inline bool page_is_mergeable(const struct bio_vec *bv,
- struct page *page, unsigned int len, unsigned int off,
- bool *same_page)
+static bool bvec_try_merge_page(struct bio_vec *bv, struct page *page,
+ unsigned int len, unsigned int off, bool *same_page)
{
size_t bv_end = bv->bv_offset + bv->bv_len;
phys_addr_t vec_end_addr = page_to_phys(bv->bv_page) + bv_end - 1;
@@ -919,38 +918,14 @@ static inline bool page_is_mergeable(const struct bio_vec *bv,
return false;
*same_page = ((vec_end_addr & PAGE_MASK) == page_addr);
- if (*same_page)
- return true;
- else if (IS_ENABLED(CONFIG_KMSAN))
- return false;
- return (bv->bv_page + bv_end / PAGE_SIZE) == (page + off / PAGE_SIZE);
-}
-
-/**
- * __bio_try_merge_page - try appending data to an existing bvec.
- * @bio: destination bio
- * @page: start page to add
- * @len: length of the data to add
- * @off: offset of the data relative to @page
- * @same_page: return if the segment has been merged inside the same page
- *
- * Try to add the data at @page + @off to the last bvec of @bio. This is a
- * useful optimisation for file systems with a block size smaller than the
- * page size.
- *
- * Warn if (@len, @off) crosses pages in case that @same_page is true.
- *
- * Return %true on success or %false on failure.
- */
-static bool __bio_try_merge_page(struct bio *bio, struct page *page,
- unsigned int len, unsigned int off, bool *same_page)
-{
- struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
+ if (!*same_page) {
+ if (IS_ENABLED(CONFIG_KMSAN))
+ return false;
+ if (bv->bv_page + bv_end / PAGE_SIZE != page + off / PAGE_SIZE)
+ return false;
+ }
- if (!page_is_mergeable(bv, page, len, off, same_page))
- return false;
bv->bv_len += len;
- bio->bi_iter.bi_size += len;
return true;
}
@@ -972,7 +947,7 @@ static bool bio_try_merge_hw_seg(struct request_queue *q, struct bio *bio,
return false;
if (bv->bv_len + len > queue_max_segment_size(q))
return false;
- return __bio_try_merge_page(bio, page, len, offset, same_page);
+ return bvec_try_merge_page(bv, page, len, offset, same_page);
}
/**
@@ -1001,8 +976,11 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
return 0;
if (bio->bi_vcnt > 0) {
- if (bio_try_merge_hw_seg(q, bio, page, len, offset, same_page))
+ if (bio_try_merge_hw_seg(q, bio, page, len, offset,
+ same_page)) {
+ bio->bi_iter.bi_size += len;
return len;
+ }
if (bio->bi_vcnt >=
min(bio->bi_max_vecs, queue_max_segments(q)))
@@ -1123,8 +1101,11 @@ int bio_add_page(struct bio *bio, struct page *page,
return 0;
if (bio->bi_vcnt > 0 &&
- __bio_try_merge_page(bio, page, len, offset, &same_page))
+ bvec_try_merge_page(&bio->bi_io_vec[bio->bi_vcnt - 1],
+ page, len, offset, &same_page)) {
+ bio->bi_iter.bi_size += len;
return len;
+ }
if (bio->bi_vcnt >= bio->bi_max_vecs)
return 0;
@@ -1206,7 +1187,9 @@ static int bio_iov_add_page(struct bio *bio, struct page *page,
return -EIO;
if (bio->bi_vcnt > 0 &&
- __bio_try_merge_page(bio, page, len, offset, &same_page)) {
+ bvec_try_merge_page(&bio->bi_io_vec[bio->bi_vcnt - 1],
+ page, len, offset, &same_page)) {
+ bio->bi_iter.bi_size += len;
if (same_page)
bio_release_page(bio, page);
return 0;
--
2.39.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
end of thread, other threads:[~2023-07-24 16:54 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-12 13:38 rationalize the flow in bio_add_page and friends Christoph Hellwig
2023-05-12 13:38 ` [PATCH 1/8] block: tidy up the bio full checks in bio_add_hw_page Christoph Hellwig
2023-05-17 7:18 ` Jinyoung CHOI
2023-05-12 13:38 ` [PATCH 2/8] block: use SECTOR_SHIFT bio_add_hw_page Christoph Hellwig
2023-05-16 12:00 ` Johannes Thumshirn
2023-05-19 6:05 ` Jinyoung CHOI
2023-05-12 13:38 ` [PATCH 3/8] block: move the BIO_CLONED checks out of __bio_try_merge_page Christoph Hellwig
2023-05-16 12:01 ` Johannes Thumshirn
2023-05-19 6:08 ` Jinyoung CHOI
2023-05-12 13:38 ` [PATCH 4/8] block: move the bi_vcnt check " Christoph Hellwig
2023-05-16 12:04 ` Johannes Thumshirn
2023-05-19 6:13 ` Jinyoung CHOI
2023-05-12 13:38 ` [PATCH 5/8] block: move the bi_size overflow check in __bio_try_merge_page Christoph Hellwig
2023-05-16 12:08 ` Johannes Thumshirn
2023-05-19 6:14 ` Jinyoung CHOI
2023-05-12 13:38 ` [PATCH 6/8] block: downgrade a bio_full call in bio_add_page Christoph Hellwig
2023-05-19 6:18 ` Jinyoung CHOI
2023-05-12 13:39 ` [PATCH 7/8] block: move the bi_size update out of __bio_try_merge_page Christoph Hellwig
2023-05-19 6:27 ` Jinyoung CHOI
2023-05-12 13:39 ` [PATCH 8/8] block: don't pass a bio to bio_try_merge_hw_seg Christoph Hellwig
2023-05-19 6:30 ` Jinyoung CHOI
2023-05-19 2:27 ` rationalize the flow in bio_add_page and friends Jens Axboe
2023-05-20 1:49 ` Jens Axboe
-- strict thread matches above, loose matches on Subject: below --
2023-07-24 16:54 rationalize the flow in bio_add_page and friends v2 Christoph Hellwig
2023-07-24 16:54 ` [PATCH 7/8] block: move the bi_size update out of __bio_try_merge_page Christoph Hellwig
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).