On Fri, Apr 26, 2024 at 08:18:44AM -0700, Darrick J. Wong wrote: > On Thu, Apr 25, 2024 at 01:37:43PM +0200, 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> > > Didn't this already go in for-next? I don't think so. I think Christoph suggested to have it in the LBS series and see if MM folks can fix the issue upstream.[1] [1] https://www.spinics.net/lists/linux-xfs/msg83130.html > > If not, > Reviewed-by: Darrick J. Wong <djwong@xxxxxxxxxx> > > --D > > > --- > > 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 ac904cc1a97b..969abc6efd70 100644 > > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > > @@ -1059,10 +1059,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; > > @@ -1125,7 +1122,7 @@ xfs_attr3_leaf_to_shortform( > > error = 0; > > > > out: > > - kfree(tmpbuffer); > > + kvfree(tmpbuffer); > > return error; > > } > > > > @@ -1533,7 +1530,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; > > @@ -1571,7 +1568,7 @@ xfs_attr3_leaf_compact( > > */ > > xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1); > > > > - kfree(tmpbuffer); > > + kvfree(tmpbuffer); > > } > > > > /* > > @@ -2250,7 +2247,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); > > > > /* > > @@ -2291,7 +2288,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.34.1 > > > >