[PATCH] dbg mapping_ptr
From: Huang Ying
Date: Thu Mar 09 2023 - 02:29:58 EST
---
mm/rmap.c | 28 ++++++++++++++++++++--------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/mm/rmap.c b/mm/rmap.c
index 8632e02661ac..50ee208baff9 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -466,6 +466,13 @@ void __init anon_vma_init(void)
SLAB_PANIC|SLAB_ACCOUNT);
}
=20
+union mapping_ptr {
+ struct address_space *mapping;
+ unsigned long tag;
+ struct anon_vma *anon_vma;
+ struct movable_operations *mops;
+};
+
/*
* Getting a lock on a stable anon_vma from a page off the LRU is tricky!
*
@@ -493,16 +500,17 @@ void __init anon_vma_init(void)
struct anon_vma *folio_get_anon_vma(struct folio *folio)
{
struct anon_vma *anon_vma =3D NULL;
- unsigned long anon_mapping;
+ union mapping_ptr mptr;
=20
rcu_read_lock();
- anon_mapping =3D (unsigned long)READ_ONCE(folio->mapping);
- if ((anon_mapping & PAGE_MAPPING_FLAGS) !=3D PAGE_MAPPING_ANON)
+ mptr.mapping =3D READ_ONCE(folio->mapping);
+ if ((mptr.tag & PAGE_MAPPING_FLAGS) !=3D PAGE_MAPPING_ANON)
goto out;
if (!folio_mapped(folio))
goto out;
=20
- anon_vma =3D (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON);
+ mptr.tag &=3D ~PAGE_MAPPING_FLAGS;
+ anon_vma =3D mptr.anon_vma;
if (!atomic_inc_not_zero(&anon_vma->refcount)) {
anon_vma =3D NULL;
goto out;
@@ -1115,18 +1123,20 @@ int folio_total_mapcount(struct folio *folio)
void page_move_anon_rmap(struct page *page, struct vm_area_struct *vma)
{
void *anon_vma =3D vma->anon_vma;
+ union mapping_ptr mptr;
struct folio *folio =3D page_folio(page);
=20
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
VM_BUG_ON_VMA(!anon_vma, vma);
=20
- anon_vma +=3D PAGE_MAPPING_ANON;
+ mptr.anon_vma =3D anon_vma;
+ mptr.tag |=3D PAGE_MAPPING_ANON;
/*
* Ensure that anon_vma and the PAGE_MAPPING_ANON bit are written
* simultaneously, so a concurrent reader (eg folio_referenced()'s
* folio_test_anon()) will not see one without the other.
*/
- WRITE_ONCE(folio->mapping, anon_vma);
+ WRITE_ONCE(folio->mapping, mptr.mapping);
SetPageAnonExclusive(page);
}
=20
@@ -1142,6 +1152,7 @@ static void __page_set_anon_rmap(struct folio *folio,=
struct page *page,
struct vm_area_struct *vma, unsigned long address, int exclusive)
{
struct anon_vma *anon_vma =3D vma->anon_vma;
+ union mapping_ptr mptr;
=20
BUG_ON(!anon_vma);
=20
@@ -1162,8 +1173,9 @@ static void __page_set_anon_rmap(struct folio *folio,=
struct page *page,
* the PAGE_MAPPING_ANON type identifier, otherwise the rmap code
* could mistake the mapping for a struct address_space and crash.
*/
- anon_vma =3D (void *) anon_vma + PAGE_MAPPING_ANON;
- WRITE_ONCE(folio->mapping, (struct address_space *) anon_vma);
+ mptr.anon_vma =3D anon_vma;
+ mptr.tag |=3D PAGE_MAPPING_ANON;
+ WRITE_ONCE(folio->mapping, mptr.mapping);
folio->index =3D linear_page_index(vma, address);
out:
if (exclusive)
--=20
2.39.2