> 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 > / \ > VMA B VMA C > \ / > root <- anon_vma 1 > ----^ ^---- > / 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@vger.kernel.org > Reported-by: Chris Mason > Reviewed-by: Lorenzo Stoakes (ARM) > Signed-off-by: David Hildenbrand (Arm) > --- > mm/ksm.c | 36 +++++++++++++++++++++++++++++++----- > mm/util.c | 13 +++++++++++++ > 2 files changed, 44 insertions(+), 5 deletions(-) Acked-by: Xu Xin