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 |
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>
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,
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 --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);