On Tue, Jun 25, 2024 at 11:44:17AM +0000, Pankaj Raghav (Samsung) wrote: > From: Dave Chinner <dchinner@xxxxxxxxxx> > > Pankaj Raghav reported that when filesystem block size is larger > than page size, the xattr code can use kmalloc() for high order > allocations. This triggers a useless warning in the allocator as it > is a __GFP_NOFAIL allocation here: > > static inline > struct page *rmqueue(struct zone *preferred_zone, > struct zone *zone, unsigned int order, > gfp_t gfp_flags, unsigned int alloc_flags, > int migratetype) > { > struct page *page; > > /* > * We most definitely don't want callers attempting to > * allocate greater than order-1 page units with __GFP_NOFAIL. > */ > >>>> WARN_ON_ONCE((gfp_flags & __GFP_NOFAIL) && (order > 1)); > ... > > Fix this by changing all these call sites to use kvmalloc(), which > will strip the NOFAIL from the kmalloc attempt and if that fails > will do a __GFP_NOFAIL vmalloc(). > > This is not an issue that productions systems will see as > filesystems with block size > page size cannot be mounted by the > kernel; Pankaj is developing this functionality right now. > > Reported-by: Pankaj Raghav <kernel@xxxxxxxxxxxxxxxx> > Fixes: f078d4ea8276 ("xfs: convert kmem_alloc() to kmalloc()") > Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> > Reviewed-by: Darrick J. Wong <djwong@xxxxxxxxxx> > Reviewed-by: Pankaj Raghav <p.raghav@xxxxxxxxxxx> @Chandan: As we discussed today, do you want to pick this up for 6.11? Then I can drop it from my patch series. > --- > fs/xfs/libxfs/xfs_attr_leaf.c | 15 ++++++--------- > 1 file changed, 6 insertions(+), 9 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > index b9e98950eb3d..09f4cb061a6e 100644 > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > @@ -1138,10 +1138,7 @@ xfs_attr3_leaf_to_shortform( > > trace_xfs_attr_leaf_to_sf(args); > > - tmpbuffer = kmalloc(args->geo->blksize, GFP_KERNEL | __GFP_NOFAIL); > - if (!tmpbuffer) > - return -ENOMEM; > - > + tmpbuffer = kvmalloc(args->geo->blksize, GFP_KERNEL | __GFP_NOFAIL); > memcpy(tmpbuffer, bp->b_addr, args->geo->blksize); > > leaf = (xfs_attr_leafblock_t *)tmpbuffer; > @@ -1205,7 +1202,7 @@ xfs_attr3_leaf_to_shortform( > error = 0; > > out: > - kfree(tmpbuffer); > + kvfree(tmpbuffer); > return error; > } > > @@ -1613,7 +1610,7 @@ xfs_attr3_leaf_compact( > > trace_xfs_attr_leaf_compact(args); > > - tmpbuffer = kmalloc(args->geo->blksize, GFP_KERNEL | __GFP_NOFAIL); > + tmpbuffer = kvmalloc(args->geo->blksize, GFP_KERNEL | __GFP_NOFAIL); > memcpy(tmpbuffer, bp->b_addr, args->geo->blksize); > memset(bp->b_addr, 0, args->geo->blksize); > leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; > @@ -1651,7 +1648,7 @@ xfs_attr3_leaf_compact( > */ > xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1); > > - kfree(tmpbuffer); > + kvfree(tmpbuffer); > } > > /* > @@ -2330,7 +2327,7 @@ xfs_attr3_leaf_unbalance( > struct xfs_attr_leafblock *tmp_leaf; > struct xfs_attr3_icleaf_hdr tmphdr; > > - tmp_leaf = kzalloc(state->args->geo->blksize, > + tmp_leaf = kvzalloc(state->args->geo->blksize, > GFP_KERNEL | __GFP_NOFAIL); > > /* > @@ -2371,7 +2368,7 @@ xfs_attr3_leaf_unbalance( > } > memcpy(save_leaf, tmp_leaf, state->args->geo->blksize); > savehdr = tmphdr; /* struct copy */ > - kfree(tmp_leaf); > + kvfree(tmp_leaf); > } > > xfs_attr3_leaf_hdr_to_disk(state->args->geo, save_leaf, &savehdr); > -- > 2.44.1 >