Re: Hang with xfs/285 on 2026-03-02 kernel

Ritesh Harjani
2026-04-05T01:38:23Z

Dave Chinner <dgc@kernel.org> writes:

> On Fri, Apr 03, 2026 at 04:35:46PM +0100, Matthew Wilcox wrote:
>> This is with commit 5619b098e2fb so after 7.0-rc6
>> INFO: task fsstress:3762792 blocked on a semaphore likely last held by task fsstress:3762793
>> task:fsstress state:D stack:0 pid:3762793 tgid:3762793 ppid:3762783 task_flags:0x440140 flags:0x00080800
>> Call Trace:
>> <TASK>
>> __schedule+0x560/0xfc0
>> schedule+0x3e/0x140
>> schedule_timeout+0x84/0x110
>> ? __pfx_process_timeout+0x10/0x10
>> io_schedule_timeout+0x5b/0x80
>> xfs_buf_alloc+0x793/0x7d0
>
> -ENOMEM.
>
> It'll be looping here:
>
> fallback:
> for (;;) {
> bp->b_addr = __vmalloc(size, gfp_mask);
> if (bp->b_addr)
> break;
> if (flags & XBF_READ_AHEAD)
> return -ENOMEM;
> XFS_STATS_INC(bp->b_mount, xb_page_retries);
> memalloc_retry_wait(gfp_mask);
> }
>
> If it is looping here long enough to trigger the hang check timer,
> then the MM subsystem is not making progress reclaiming memory. This

Hi Dave,

If that's the case and if we expect the MM subsystem to do memory
reclaim, shouldn't we be passing the __GFP_DIRECT_RECLAIM flag to our
fallback loop? I see that we might have cleared this flag and also set
__GFP_NORETRY, in the above if condition if allocation size is >PAGE_SIZE.

So shouldn't we do?

if (size > PAGE_SIZE) {
if (!is_power_of_2(size))
goto fallback;
- gfp_mask &= ~__GFP_DIRECT_RECLAIM;
- gfp_mask |= __GFP_NORETRY;
+ gfp_t alloc_gfp = (gfp_mask & ~__GFP_DIRECT_RECLAIM) | __GFP_NORETRY;
+ folio = folio_alloc(alloc_gfp, get_order(size));
+ } else {
+ folio = folio_alloc(gfp_mask, get_order(size));
}
- folio = folio_alloc(gfp_mask, get_order(size));
if (!folio) {
if (size <= PAGE_SIZE)
return -ENOMEM;
trace_xfs_buf_backing_fallback(bp, _RET_IP_);
goto fallback;
}

-ritesh

> is probably a 16kB allocation (it's an inode cluster buffer), and
> the allocation context is NOFAIL because it is within a transaction
> (this loop pre-dates __vmalloc() supporting __GFP_NOFAIL)....
>
> All the other tasks are backed up on the AGI buffer lock held ...
>
>> xfs_buf_get_map+0x651/0xbd0
>> ? _raw_spin_unlock+0x26/0x50
>> xfs_trans_get_buf_map+0x141/0x300
>> xfs_ialloc_inode_init+0x130/0x2c0
>> xfs_ialloc_ag_alloc+0x226/0x710
>> xfs_dialloc+0x22d/0x980
>
> ... here by the task blocked on memory allocation.
>
> This smells like a persistent ENOMEM/memory reclaim issue and XFS is
> just the messenger...
>
> -Dave.
> --
> Dave Chinner
> dgc@kernel.org