Re: [PATCH 04/25] mm/fbatch: lru bit set, no extra ref, while folio on per-cpu fbatch
From: Hugh Dickins
Date: Fri Aug 28 2026 - 04:05:01 EST
On Thu, 27 Aug 2026, Kiryl Shutsemau wrote:
> On Mon, Aug 24, 2026 at 07:01:20AM -0700, Hugh Dickins wrote:
> > Treat folios on a per-cpu fbatch as if they were already on the lruvec:
> > with PG_lru set, without holding an extra reference. This will enable
> > the removal of most lru_add_drain() and lru_add_drain_all() calls soon.
> >
> > Recognize such a folio by 0x02 set in the folio->lru.next pointer by
> > folio_add_lru().
>
> Hm. pfmemalloc (__GFP_MEMALLOC) thingy already claims the bit. Is it
> safe because such memory is never on LRU?
>
> Are pfmemalloc and PG_lru mutually exclusive?
>
> Do we want to be explicit about this? Like, folio/page_is_pfmemalloc()
> shouldn't return true for PG_lru folios/pages or something.
Gosh, thanks so much for pointing that out: I was completely ignorant
of the the pfmemalloc use, and a bit (bit 1!) shocked to learn of it
(why wouldn't they just reuse a pageflag, I wonder? but doesn't matter).
Anyway, as you've rightly guessed, it's not a problem at all: these
mm/folio.c and mm/mlock.c per-cpu fbatches are entirely for folios;
and if any pfmemalloced page ever get used for a folio (dunno) and
put on an fbatch for LRU, then of course its use of lru.next is
immediately overwritten (first by what this patch writes in lru_next,
then later by the lru.next pointer for whatever LRU it goes on to -
just as before this patch).
If you were to tell me that some subsystem uses PG_lru for some
other purpose, then I would have to get more worried; but we can
be fairly sure that's not so, since mm/compaction.c for one relies
on konwing it's free to play with PG_lru folios.
Whether a folio is ever allocated with __GFP_MEMALLOC, I'm not
certain (haven't looked), but there is no need to exclude that:
it simply would not retain that page_is_pfmemalloc() info across
folio_add_lru().
Does stable_page_flags() present page_is_pfmemalloc() as a KPF
flag? No, it does not, so no problem there either.
This certainly deserves a comment somewhere, but not a problem.
Thanks!
Hugh
p.s. Only in replying do I come to realize that I don't actually
need that bit myself now (we could just put one magic value there).
It comes from all along when I believed it important to be able to
distinguish expected from unexpected entries, then suddenly realized
that actually they want identical treatment, so no need to distinguish.
The lru_add entry pointer is still kept in lru_next, but only to help
in debug. But I would like to go on this way, using the bit, for now:
partly because I'm wary of well-intentioned last-minute changes,
partly because I'm not certain a reason to distinguish won't emerge.