diff mbox series

[v5,1/3] block: Added folio-lized version of bio_add_hw_page()

Message ID 20240619023420.34527-2-kundan.kumar@samsung.com (mailing list archive)
State New
Headers show
Series block: add larger order folio instead of pages | expand

Commit Message

Kundan Kumar June 19, 2024, 2:34 a.m. UTC
Added new bio_add_hw_folio() function. This is a prep patch.

Signed-off-by: Kundan Kumar <kundan.kumar@samsung.com>
---
 block/bio.c | 38 +++++++++++++++++++++++++++++---------
 block/blk.h |  4 ++++
 2 files changed, 33 insertions(+), 9 deletions(-)

--
2.25.1

Comments

Matthew Wilcox June 20, 2024, 3:47 a.m. UTC | #1
On Wed, Jun 19, 2024 at 08:04:18AM +0530, Kundan Kumar wrote:
>  /**
> - * bio_add_hw_page - attempt to add a page to a bio with hw constraints
> + * bio_add_hw_page - a wrapper around function bio_add_hw_folio

No.  You haven't changed what this function does, merely how it is
implemented.  The reader of the API documentation doesn't care about the
implementation, they just need to know what it does.

>   * @q: the target queue
>   * @bio: destination bio
>   * @page: page to add
> @@ -972,13 +972,35 @@ bool bvec_try_merge_hw_page(struct request_queue *q, struct bio_vec *bv,
>   * @offset: vec entry offset
>   * @max_sectors: maximum number of sectors that can be added
>   * @same_page: return if the segment has been merged inside the same page
> - *
> - * Add a page to a bio while respecting the hardware max_sectors, max_segment
> - * and gap limitations.

Likewise.

> +/**
> + * bio_add_hw_folio - attempt to add a folio to a bio with hw constraints
> + * @q: the target queue
> + * @bio: destination bio
> + * @folio: folio to add
> + * @len: vec entry length
> + * @offset: vec entry offset in the folio
> + * @max_sectors: maximum number of sectors that can be added
> + * @same_page: return if the segment has been merged inside the same page

... page?

> + * Add a folio to a bio while respecting the hardware max_sectors, max_segment
> + * and gap limitations.
> + */
> +int bio_add_hw_folio(struct request_queue *q, struct bio *bio,
> +               struct folio *folio, unsigned int len, unsigned int offset,

size_t for both of these parameters.  We're dangerously close to
overflowing unsigned int (arm64 gets to 512MB folios, which is only 3
bits from 4GB).
diff mbox series

Patch

diff --git a/block/bio.c b/block/bio.c
index e9e809a63c59..c8914febb16e 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -964,7 +964,7 @@  bool bvec_try_merge_hw_page(struct request_queue *q, struct bio_vec *bv,
 }

 /**
- * bio_add_hw_page - attempt to add a page to a bio with hw constraints
+ * bio_add_hw_page - a wrapper around function bio_add_hw_folio
  * @q: the target queue
  * @bio: destination bio
  * @page: page to add
@@ -972,13 +972,35 @@  bool bvec_try_merge_hw_page(struct request_queue *q, struct bio_vec *bv,
  * @offset: vec entry offset
  * @max_sectors: maximum number of sectors that can be added
  * @same_page: return if the segment has been merged inside the same page
- *
- * Add a page to a bio while respecting the hardware max_sectors, max_segment
- * and gap limitations.
  */
 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 folio *folio = page_folio(page);
+       size_t folio_offset = (folio_page_idx(folio, page) << PAGE_SHIFT) +
+                              offset;
+
+       return bio_add_hw_folio(q, bio, folio, len, folio_offset, max_sectors,
+                               same_page);
+}
+
+/**
+ * bio_add_hw_folio - attempt to add a folio to a bio with hw constraints
+ * @q: the target queue
+ * @bio: destination bio
+ * @folio: folio to add
+ * @len: vec entry length
+ * @offset: vec entry offset in the folio
+ * @max_sectors: maximum number of sectors that can be added
+ * @same_page: return if the segment has been merged inside the same page
+ *
+ * Add a folio to a bio while respecting the hardware max_sectors, max_segment
+ * and gap limitations.
+ */
+int bio_add_hw_folio(struct request_queue *q, struct bio *bio,
+               struct folio *folio, unsigned int len, unsigned int offset,
+               unsigned int max_sectors, bool *same_page)
 {
        unsigned int max_size = max_sectors << SECTOR_SHIFT;

@@ -992,8 +1014,8 @@  int bio_add_hw_page(struct request_queue *q, struct bio *bio,
        if (bio->bi_vcnt > 0) {
                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)) {
+               if (bvec_try_merge_hw_page(q, bv, folio_page(folio, 0), len,
+                                          offset, same_page)) {
                        bio->bi_iter.bi_size += len;
                        return len;
                }
@@ -1010,9 +1032,7 @@  int bio_add_hw_page(struct request_queue *q, struct bio *bio,
                        return 0;
        }

-       bvec_set_page(&bio->bi_io_vec[bio->bi_vcnt], page, len, offset);
-       bio->bi_vcnt++;
-       bio->bi_iter.bi_size += len;
+       bio_add_folio_nofail(bio, folio, len, offset);
        return len;
 }

diff --git a/block/blk.h b/block/blk.h
index 79e8d5d4fe0c..d0bec44a2ffb 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -524,6 +524,10 @@  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);

+int bio_add_hw_folio(struct request_queue *q, struct bio *bio,
+               struct folio *folio, unsigned int len, unsigned int offset,
+               unsigned int max_sectors, bool *same_page);
+
 /*
  * Clean up a page appropriately, where the page may be pinned, may have a
  * ref taken on it or neither.