Re: [PATCH v4 12/17] mm/huge_memory: mark folio as accessed more accurately on split

From: Kairui Song

Date: Sun Nov 08 2026 - 22:23:12 EST


On Mon, Nov 9, 2026 at 6:15 AM Barry Song <baohua@xxxxxxxxxx> wrote:
>
> On Fri, Oct 16, 2026 at 2:16 AM Kairui Song via B4 Relay
> <devnull+kasong.tencent.com@xxxxxxxxxx> wrote:
> >
> > From: Kairui Song <kasong@xxxxxxxxxxx>
> >
> > The behavior of updating the folio's access info isn't consistent for
> > huge mapping splitting or ordinary unmapping. The page table's young
> > flag has to be translated into folio's access info.
> >
> > Right now it only check and set folio's referenced flag, which isn't
> > enough since folio flags update on access have its rules. Ordinary
> > unmapping (zapping) calls folio_mark_accessed(), and it also checks
> > if the VMA has recency to avoid false updates.
>
> This might be a bit off-topic, but I once proposed
> recency fading for the zapping case in Android workloads:
>
> https://lore.kernel.org/linux-mm/20250514070820.51793-1-21cnbao@xxxxxxxxx/
>
> folio_mark_accessed() might not be ideal for Android
> apps that are being killed, as we expect them to be
> relaunched only after a long period of time.
>
> But for the splitting case, I guess there is no doubt
> that the accessed state should be set.

Hi Barry,

Thanks for the review.

I agree with these points. BTW that recency fading patch seems
interesting too, but perhaps we need something stronger than
folio_maybe_mapped_shared, maybe folio_maybe_shared, and do that when
"current's cgroup matches the folio's cgroup and have a ref count ~=
1"?

> > @@ -3216,8 +3216,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
> > folio = page_folio(page);
> > if (!folio_test_dirty(folio) && pmd_dirty(old_pmd))
> > folio_mark_dirty(folio);
> > - if (!folio_test_referenced(folio) && pmd_young(old_pmd))
> > - folio_set_referenced(folio);
> > + if (pmd_young(old_pmd) && vma_has_recency(vma))
> > + folio_mark_accessed(folio);
>
> We now have two inc_refs paths:
>
> - folio_inc_lru_refs_walk() for mapped folios;
> - folio_inc_lru_refs() for syscall accesses, or possibly
> mapped folios with the appropriate flags such as
> LRU_REF_MAPPED, LRU_REF_EXEC, LRU_REF_FORCE, etc.
>
> The interface is:
>
> void folio_inc_lru_refs(struct folio *folio, unsigned int flags);
>
> Here we call folio_mark_accessed(folio), which is the
> syscall path with flags = 0:
>
> folio_inc_lru_refs(folio, 0);
>
> Are we somehow applying the syscall access policy to
> folios accessed through the page table?

Right at this point I'm just trying to stick with the current upstream
behavior, and not promote these folios aggressively. The results are
looking OK for end to end benchmarks so far, maybe they can be tweaked
further like a LRU_REF_MEAN so it won't promote them, just inc the
ref, I didn't find any oberable differenence at this point as THP
alloc success rate is very low when under pressure so sticking with
the current behavior seems not a bad idea.