diff mbox series

[V2] block: fix adding folio to bio

Message ID 20250312145136.2891229-1-ming.lei@redhat.com (mailing list archive)
State New
Headers show
Series [V2] block: fix adding folio to bio | expand

Commit Message

Ming Lei March 12, 2025, 2:51 p.m. UTC
>4GB folio is possible on some ARCHs, such as aarch64, 16GB hugepage
is supported, then 'offset' of folio can't be held in 'unsigned int',
cause warning in bio_add_folio_nofail() and IO failure.

Fix it by adjusting 'page' & trimming 'offset' so that `->bi_offset` won't
be overflow, and folio can be added to bio successfully.

Fixes: ed9832bc08db ("block: introduce folio awareness and add a bigger size from folio")
Cc: Kundan Kumar <kundan.kumar@samsung.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: Gavin Shan <gshan@redhat.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
V2:
	- trim `offset` unconditionally(Matthew)
	- cover bio_add_folio() too (Matthew)
	

 block/bio.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

Comments

Matthew Wilcox March 12, 2025, 3:49 p.m. UTC | #1
On Wed, Mar 12, 2025 at 10:51:36PM +0800, Ming Lei wrote:
> >4GB folio is possible on some ARCHs, such as aarch64, 16GB hugepage
> is supported, then 'offset' of folio can't be held in 'unsigned int',
> cause warning in bio_add_folio_nofail() and IO failure.
> 
> Fix it by adjusting 'page' & trimming 'offset' so that `->bi_offset` won't
> be overflow, and folio can be added to bio successfully.
> 
> Fixes: ed9832bc08db ("block: introduce folio awareness and add a bigger size from folio")
> Cc: Kundan Kumar <kundan.kumar@samsung.com>
> Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Luis Chamberlain <mcgrof@kernel.org>
> Cc: Gavin Shan <gshan@redhat.com>
> Signed-off-by: Ming Lei <ming.lei@redhat.com>

Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Jens Axboe March 12, 2025, 8:07 p.m. UTC | #2
On Wed, 12 Mar 2025 22:51:36 +0800, Ming Lei wrote:
> >4GB folio is possible on some ARCHs, such as aarch64, 16GB hugepage
> is supported, then 'offset' of folio can't be held in 'unsigned int',
> cause warning in bio_add_folio_nofail() and IO failure.
> 
> Fix it by adjusting 'page' & trimming 'offset' so that `->bi_offset` won't
> be overflow, and folio can be added to bio successfully.
> 
> [...]

Applied, thanks!

[1/1] block: fix adding folio to bio
      commit: 26064d3e2b4d9a14df1072980e558c636fb023ea

Best regards,
Gavin Shan March 13, 2025, 1:08 a.m. UTC | #3
On 3/13/25 12:51 AM, Ming Lei wrote:
>> 4GB folio is possible on some ARCHs, such as aarch64, 16GB hugepage
> is supported, then 'offset' of folio can't be held in 'unsigned int',
> cause warning in bio_add_folio_nofail() and IO failure.
> 
> Fix it by adjusting 'page' & trimming 'offset' so that `->bi_offset` won't
> be overflow, and folio can be added to bio successfully.
> 
> Fixes: ed9832bc08db ("block: introduce folio awareness and add a bigger size from folio")
> Cc: Kundan Kumar <kundan.kumar@samsung.com>
> Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Luis Chamberlain <mcgrof@kernel.org>
> Cc: Gavin Shan <gshan@redhat.com>
> Signed-off-by: Ming Lei <ming.lei@redhat.com>
> ---
> V2:
> 	- trim `offset` unconditionally(Matthew)
> 	- cover bio_add_folio() too (Matthew)
> 	
> 
>   block/bio.c | 11 +++++++----
>   1 file changed, 7 insertions(+), 4 deletions(-)
> 

Thanks for fixing it quickly, Ming. It fixes my issue where the guest can't boot
successfully when 16GB hugetlb pages are used on ARM64 host. With this applied,
the guest can boot up successfully.

Tested-by: Gavin Shan <gshan@redhat.com>

> diff --git a/block/bio.c b/block/bio.c
> index f0c416e5931d..42392dd989ec 100644
> --- a/block/bio.c
> +++ b/block/bio.c
> @@ -1026,9 +1026,10 @@ EXPORT_SYMBOL(bio_add_page);
>   void bio_add_folio_nofail(struct bio *bio, struct folio *folio, size_t len,
>   			  size_t off)
>   {
> +	unsigned long nr = off / PAGE_SIZE;
> +
>   	WARN_ON_ONCE(len > UINT_MAX);
> -	WARN_ON_ONCE(off > UINT_MAX);
> -	__bio_add_page(bio, &folio->page, len, off);
> +	__bio_add_page(bio, folio_page(folio, nr), len, off % PAGE_SIZE);
>   }
>   EXPORT_SYMBOL_GPL(bio_add_folio_nofail);
>   
> @@ -1049,9 +1050,11 @@ EXPORT_SYMBOL_GPL(bio_add_folio_nofail);
>   bool bio_add_folio(struct bio *bio, struct folio *folio, size_t len,
>   		   size_t off)
>   {
> -	if (len > UINT_MAX || off > UINT_MAX)
> +	unsigned long nr = off / PAGE_SIZE;
> +
> +	if (len > UINT_MAX)
>   		return false;
> -	return bio_add_page(bio, &folio->page, len, off) > 0;
> +	return bio_add_page(bio, folio_page(folio, nr), len, off % PAGE_SIZE) > 0;
>   }
>   EXPORT_SYMBOL(bio_add_folio);
>
diff mbox series

Patch

diff --git a/block/bio.c b/block/bio.c
index f0c416e5931d..42392dd989ec 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1026,9 +1026,10 @@  EXPORT_SYMBOL(bio_add_page);
 void bio_add_folio_nofail(struct bio *bio, struct folio *folio, size_t len,
 			  size_t off)
 {
+	unsigned long nr = off / PAGE_SIZE;
+
 	WARN_ON_ONCE(len > UINT_MAX);
-	WARN_ON_ONCE(off > UINT_MAX);
-	__bio_add_page(bio, &folio->page, len, off);
+	__bio_add_page(bio, folio_page(folio, nr), len, off % PAGE_SIZE);
 }
 EXPORT_SYMBOL_GPL(bio_add_folio_nofail);
 
@@ -1049,9 +1050,11 @@  EXPORT_SYMBOL_GPL(bio_add_folio_nofail);
 bool bio_add_folio(struct bio *bio, struct folio *folio, size_t len,
 		   size_t off)
 {
-	if (len > UINT_MAX || off > UINT_MAX)
+	unsigned long nr = off / PAGE_SIZE;
+
+	if (len > UINT_MAX)
 		return false;
-	return bio_add_page(bio, &folio->page, len, off) > 0;
+	return bio_add_page(bio, folio_page(folio, nr), len, off % PAGE_SIZE) > 0;
 }
 EXPORT_SYMBOL(bio_add_folio);