Re: [PATCHv2] mm/huge_memory: do not add dropped split tail folios to LRU

From: Zhaoyang Huang

Date: Fri Jun 12 2026 - 01:53:23 EST


On Fri, Jun 12, 2026 at 1:17 PM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote:
>
> On Fri, Jun 12, 2026 at 10:34:56AM +0800, zhaoyang.huang wrote:
> > [2]
> > *F: big folio before split
> > *T: tail folio after split
> > CPU0 (f2fs GC) CPU1 (split_folio_to_order) CPU2 (folio_isolate_lru)
> > *F: pagecache refs = n
> > *F: extra refs = split
> > *F: PG_lru set, mapping != NULL
> > split_folio_to_order(F)
> > folio_ref_freeze(F, 1)
>
> I'll stop you right there. folio_ref_freeze() is called with
> folio_cache_ref_count(folio) + 1. That's defined as:
yes, it is a typo. The right one is folio_ref_freeze(F, n+1). The
folio could be split successfully by __folio_freeze_and_split_unmapped
and have all pages added to LRU then. The race window is the later
free_folio_and_swap_cache->folio_put_textzero vs
folio_isolate_lru->folio_clear_lru which lack synchronization between
and left a folio in LRU but !PG_lru.
>
> static unsigned int folio_cache_ref_count(const struct folio *folio)
> {
> if (folio_test_anon(folio) && !folio_test_swapcache(folio))
> return 0;
> return folio_nr_pages(folio);
> }
>
> so you'd have to freeze it with 2^order + 1. The 2^order is the number of
> references the page cache takes on it and the 1 is the reference held by
> the caller of split_folio_to_order(). If anybody else has a reference
> to it at this point, the call to freeze will fail.
>