Re: [PATCH] mm/huge_memory: Initialise workingset state before folio split

From: Zi Yan

Date: Fri Jul 24 2026 - 23:16:30 EST


On 24 Jul 2026, at 16:26, Zi Yan wrote:

> Use Lorenzo’s current email.
>
> On 24 Jul 2026, at 16:18, Zi Yan wrote:
>
>> On 24 Jul 2026, at 15:52, Matt Fleming wrote:
>>
>>> From: Matt Fleming <mfleming@xxxxxxxxxxxxxx>
>>>
>>> xas_try_split() adds __GFP_ACCOUNT for page-cache xa_nodes, but
>>> __folio_split() leaves the xa_state's xa_lru unset. That lets a live,
>>
>> But mapping_set_update() is not required for xas_split_alloc() and xas_split(),
>> or at least nothing triggered for uniform split path. Why?
>>
>> xas_split_alloc() uses
>> gfp = current_gfp_context(mapping_gfp_mask(mapping) & GFP_RECLAIM_MASK),
>> whereas xas_try_split() starts with GFP_NOWAIT and follows xas_nomem()
>> by adding __GFP_ACCOUNT if XA_FLAGS_ACCOUNT is set.
>>
>> Should xas_split_alloc() also take a gfp input and the caller gets
>> gfp the same way as xas_split_alloc()?

xas_try_split() is called under the xarray lock with irq disabled, so it
cannot accept arbitrary gfp. And xas_split_alloc() is the only one does
not do

if (xas->xa->xa_flags & XA_FLAGS_ACCOUNT)
gfp |= __GFP_ACCOUNT;

the others, xas_nomem(), __xas_nomem(), and xas_alloc() all have it.
Commit 7b785645e8f13 ("mm: fix page cache convergence regression") added
the __GFP_ACCOUNT statement. I will send a patch to add it to
xas_split_alloc() with Fixes: 6b24ca4a1a8d4 ("mm: Use multi-index entries
in the page cache")

In sum, I think this patch does the right thing. And Sashiko pointed out
this issue before[1].

[1] https://sashiko.dev/#/patchset/20260716095424.471052-1-kirill@xxxxxxxxxxxxx

>>
>>> memcg-charged xa_node exist without being linked into the mapping's
>>> shadow_nodes list_lru; when reclaim later walks the list_lru it trips
>>> VM_WARN_ON(!css_is_dying()).
>>>
>>> Use mapping_set_update() to install both the workingset update callback
>>> and the shadow_nodes list_lru on the xa_state.
>>>
>>> Reported-by: syzbot+c5b060ce82921a2fd500@xxxxxxxxxxxxxxxxxxxxxxxxx
>>> Closes: https://syzkaller.appspot.com/bug?extid=c5b060ce82921a2fd500
>>> Fixes: 58729c04cf10 ("mm/huge_memory: add buddy allocator like (non-uniform) folio_split()")
>>> Cc: stable@xxxxxxxxxxxxxxx
>>> Signed-off-by: Matt Fleming <mfleming@xxxxxxxxxxxxxx>
>>> ---
>>> mm/huge_memory.c | 3 ++-
>>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
>>> index b5d1e9d4463d..12d0e0b14e83 100644
>>> --- a/mm/huge_memory.c
>>> +++ b/mm/huge_memory.c
>>> @@ -4033,7 +4033,8 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
>>> gfp_t gfp;
>>>
>>> mapping = folio->mapping;
>>> - min_order = mapping_min_folio_order(folio->mapping);
>>> + mapping_set_update(&xas, mapping);
>>> + min_order = mapping_min_folio_order(mapping);
>>> if (new_order < min_order) {
>>> ret = -EINVAL;
>>> goto out;
>>> --
>>> 2.43.0

mapping_set_update() probably can be delayed right before the if block
containing xas_split_alloc(). Otherwise, LGTM. Thanks.

Reviewed-by: Zi Yan <ziy@xxxxxxxxxx>


Best Regards,
Yan, Zi