Re: [PATCH 39/46] mm/ksm: fix use of a freed anon_vma at swap-in

From: xu . xin

Date: Thu Oct 29 2026 - 23:56:48 EST


> A folio read from a swap slot previously shared by KSM can remain in the
> swap cache after the process that first mapped it exits. Its anon_vma
> can then be freed, so ksm_might_need_to_copy() must not dereference it
> to compare roots.
>
> Doing so can result in some false-positives, resulting in the reverse
> mapping missing the new folio mapping, preventing migration and reclaim.
>
> SLAB_TYPESAFE_BY_RCU allows individual anon_vma objects to be reused
> immediately after freeing. A stale pointer can then refer to another
> anon_vma whose root matches, even though the target VMA is not linked
> to that anon_vma.
>
> Move the anonymous rmap compatibility checks into
> folio_anon_rmap_compatible(). Keep the page-index check and compare the
> folio's anon_vma pointer against the VMA's own anon_vma and root first.
>
> If neither matches, bite the bullet and walk the VMA's anon_vma_chain.
> The VMA keeps these anon_vmas alive, and finding a match guarantees that
> reverse mapping can find the new mapping.
>
> Lorenzo Stoakes says in a private discussion:
>
> "This isn't quite equivalent to the existing check.
>
> Every anon_vma in an anon_vma_chain shares the same root, but if you
> split a VMA then fork both of them like this:
>
> VMA A
> / \ <split>
> VMA B VMA C
> \ /
> root <- anon_vma 1
> ----^ ^---- <fork>
> / parent \
> anon_vma 2 anon_vma 3
> | |
> VMA D VMA E
>
> VMA's D and E both get their own new
> anon_vma's such that:
>
> VMA D: anon_vma 2 -> anon_vma 1 -> root
> VMA E: anon_vma 3 -> anon_vma 1 -> root
>
> And if you found a folio referencing anon_vma 2, the existing check:
>
> anon_vma->root == vma->anon-vma->root
>
> Would be true for VMA's B, C, D & E.
>
> However after your change it'd be true for VMA D only, as it's the only
> one with anon_vma 2 in its anon_vma_chain.
>
> Whether or not that could actually happen in practice... 🙂 I don't
> know.
>
> [...] after your change it'd be true for VMA D only, as it's the only
> one with anon_vma 2 in its anon_vma_chain. [...] I would [...] say that
> you are making the test stricter but more correct.
> "
>
> If this affects performance when KSM was never even involved, we could
> just track whether KSM ever merged anything and just skip these checks.
>
> There isn't really a lot we can do otherwise: for mapped folios we might
> be able to use folio_get_anon_vma(), but for unmapped folios there really
> is no easy way to see if the anon_vma is still valid.
>
> Document the (confusing) lifetime requirements of folio_anon_vma().
>
> Fixes: ba6f0ff3981e ("ksm: fix ksm swapin time optimization")
> Cc: stable@xxxxxxxxxxxxxxx
> Reported-by: Chris Mason <mason@xxxxxxxxxx>
> Reviewed-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
> Signed-off-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
> ---
> mm/ksm.c | 36 +++++++++++++++++++++++++++++++-----
> mm/util.c | 13 +++++++++++++
> 2 files changed, 44 insertions(+), 5 deletions(-)

Acked-by: Xu Xin <xu.xin@xxxxxxxxx>