Re: [PATCH] mm/huge_memory: fix a folio_split() race condition with folio_try_get()

From: Zi Yan

Date: Mon Mar 02 2026 - 11:41:46 EST


On 2 Mar 2026, at 9:40, David Hildenbrand (Arm) wrote:

> On 2/28/26 02:06, Zi Yan wrote:
>> During a pagecache folio split, the values in the related xarray should not
>> be changed from the original folio at xarray split time until all
>> after-split folios are well formed and stored in the xarray. Current use
>> of xas_try_split() in __split_unmapped_folio() lets some after-split folios
>> show up at wrong indices in the xarray. When these misplaced after-split
>> folios are unfrozen, before correct folios are stored via __xa_store(), and
>> grabbed by folio_try_get(), they are returned to userspace at wrong file
>> indices, causing data corruption.
>>
>> Fix it by using the original folio in xas_try_split() calls, so that
>> folio_try_get() can get the right after-split folios after the original
>> folio is unfrozen.
>>
>> Uniform split, split_huge_page*(), is not affected, since it uses
>> xas_split_alloc() and xas_split() only once and stores the original folio
>> in the xarray.
>
> Could we make both code paths similar and store the original folio in
> both cases?

Sure.

>
> IIUC, the __xa_store() is performed unconditionally after
> __split_unmapped_folio().
>
> I'm wondering, though, about the "new_folio->index >= end" case.
> Wouldn't we leave some stale entries in the xarray? But that handling
> has always been confusing to me :)

IIUC, __filemap_remove_folio() calls page_cache_delete(), which overwrites
that stale entries with shadow, which is NULL here.


Best Regards,
Yan, Zi