From: Lorenzo Stoakes <ljs@kernel.org>
To: tao <tao.wangtao@honor.com>
Cc: catalin.marinas@arm.com, will@kernel.org, tglx@kernel.org,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
x86@kernel.org, akpm@linux-foundation.org, david@kernel.org,
willy@infradead.org, sj@kernel.org, kees@kernel.org,
luizcap@redhat.com, zhangjiao2@cmss.chinamobile.com,
kas@kernel.org, hpa@zytor.com, liam@infradead.org,
vbabka@kernel.org, rppt@kernel.org, surenb@google.com,
mhocko@suse.com, jack@suse.cz, riel@surriel.com,
harry@kernel.org, jannh@google.com, jgg@ziepe.ca,
jhubbard@nvidia.com, peterx@redhat.com, ziy@nvidia.com,
baolin.wang@linux.alibaba.com, npache@redhat.com,
ryan.roberts@arm.com, dev.jain@arm.com, baohua@kernel.org,
lance.yang@linux.dev, xu.xin16@zte.com.cn,
chengming.zhou@linux.dev, nao.horiguchi@gmail.com,
matthew.brost@intel.com, joshua.hahnjy@gmail.com,
rakie.kim@sk.com, byungchul@sk.com, gourry@gourry.net,
ying.huang@linux.alibaba.com, apopple@nvidia.com,
pfalcato@suse.de, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-mm@kvack.org, damon@lists.linux.dev,
shakeel.butt@linux.dev, ryncsn@gmail.com, 21cnbao@gmail.com,
jparsana@google.com, dvander@google.com, zhangji1@honor.com,
wangzicheng@honor.com
Subject: Re: [PATCH 02/15] mm: convert anon_vma rmap APIs to anon_rmap
Date: Wed, 27 May 2026 12:49:43 +0100 [thread overview]
Message-ID: <ahbZdWDiqTCWU77K@lucifer> (raw)
In-Reply-To: <20260527110147.17815-3-tao.wangtao@honor.com>
On Wed, May 27, 2026 at 07:01:34PM +0800, tao wrote:
> Convert the rmap anon_vma interfaces to anon_rmap APIs to clarify the
> semantics of anonymous rmap operations and prepare for upcoming
> ANON_VMA_LAZY support and RCU-based lockless rmap traversal.
>
> Replace folio_anon_vma(), folio_get_anon_vma(), folio_lock_anon_vma_read(),
> anon_vma_trylock_read(), anon_vma_lock_read(), anon_vma_unlock_read(),
> anon_vma_trylock_write(), anon_vma_lock_write(), anon_vma_unlock_write(),
> and vma_interval_tree_foreach() with the anon_rmap APIs.
This is another worthless commit message. You're again just writing what you did
not why or what for. This gives no help whatsoever.
>
> No functional change intended.
Err, there is a functional change, since you're literally changing how things
iterate?
>
> Signed-off-by: tao <tao.wangtao@honor.com>
All of this is terrible, you're replacing a broken abstraction with something
that assumes something completely broken with zero explanation.
No to this.
> ---
> include/linux/rmap.h | 6 ++--
> mm/damon/ops-common.c | 4 +--
> mm/huge_memory.c | 16 +++++------
> mm/ksm.c | 43 ++++++++++++++---------------
> mm/memory-failure.c | 11 ++++----
> mm/migrate.c | 64 +++++++++++++++++++++----------------------
> mm/page_idle.c | 2 +-
> mm/rmap.c | 51 ++++++++++++++++++----------------
> 8 files changed, 98 insertions(+), 99 deletions(-)
>
> diff --git a/include/linux/rmap.h b/include/linux/rmap.h
> index c42314ea4362..9802bce92695 100644
> --- a/include/linux/rmap.h
> +++ b/include/linux/rmap.h
> @@ -997,15 +997,13 @@ struct rmap_walk_control {
> bool (*rmap_one)(struct folio *folio, struct vm_area_struct *vma,
> unsigned long addr, void *arg);
> int (*done)(struct folio *folio);
> - struct anon_vma *(*anon_lock)(const struct folio *folio,
> - struct rmap_walk_control *rwc);
> + anon_rmap_t (*anon_lock)(const struct folio *folio,
> + struct rmap_walk_control *rwc);
> bool (*invalid_vma)(struct vm_area_struct *vma, void *arg);
> };
>
> void rmap_walk(struct folio *folio, struct rmap_walk_control *rwc);
> void rmap_walk_locked(struct folio *folio, struct rmap_walk_control *rwc);
> -struct anon_vma *folio_lock_anon_vma_read(const struct folio *folio,
> - struct rmap_walk_control *rwc);
>
> bool folio_maybe_same_anon_vma(const struct folio *folio,
> const struct vm_area_struct *vma);
> diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c
> index 8c6d613425c1..5788410965b8 100644
> --- a/mm/damon/ops-common.c
> +++ b/mm/damon/ops-common.c
> @@ -172,7 +172,7 @@ void damon_folio_mkold(struct folio *folio)
> {
> struct rmap_walk_control rwc = {
> .rmap_one = damon_folio_mkold_one,
> - .anon_lock = folio_lock_anon_vma_read,
> + .anon_lock = folio_lock_anon_rmap_read,
> };
>
> if (!folio_mapped(folio) || !folio_raw_mapping(folio)) {
> @@ -236,7 +236,7 @@ bool damon_folio_young(struct folio *folio)
> struct rmap_walk_control rwc = {
> .arg = &accessed,
> .rmap_one = damon_folio_young_one,
> - .anon_lock = folio_lock_anon_vma_read,
> + .anon_lock = folio_lock_anon_rmap_read,
> };
>
> if (!folio_mapped(folio) || !folio_raw_mapping(folio)) {
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 970e077019b7..ab3c2397449a 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -4051,7 +4051,7 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
> struct folio *end_folio = folio_next(folio);
> bool is_anon = folio_test_anon(folio);
> struct address_space *mapping = NULL;
> - struct anon_vma *anon_vma = NULL;
> + anon_rmap_t anon_rmap = ANON_RMAP_NULL;
> int old_order = folio_order(folio);
> struct folio *new_folio, *next;
> int nr_shmem_dropped = 0;
> @@ -4087,12 +4087,12 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
> * is taken to serialise against parallel split or collapse
> * operations.
> */
> - anon_vma = folio_get_anon_vma(folio);
> - if (!anon_vma) {
> + anon_rmap = folio_get_anon_rmap(folio);
> + if (!anon_rmap_value(anon_rmap)) {
> ret = -EBUSY;
> goto out;
> }
> - anon_vma_lock_write(anon_vma);
> + anon_rmap_lock_write(anon_rmap);
> mapping = NULL;
> } else {
> unsigned int min_order;
> @@ -4122,7 +4122,7 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
> }
> }
>
> - anon_vma = NULL;
> + anon_rmap = ANON_RMAP_NULL;
> i_mmap_lock_read(mapping);
>
> /*
> @@ -4200,9 +4200,9 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
> }
>
> out_unlock:
> - if (anon_vma) {
> - anon_vma_unlock_write(anon_vma);
> - put_anon_vma(anon_vma);
> + if (anon_rmap_value(anon_rmap)) {
> + anon_rmap_unlock_write(anon_rmap);
> + put_anon_rmap(anon_rmap);
> }
> if (mapping)
> i_mmap_unlock_read(mapping);
> diff --git a/mm/ksm.c b/mm/ksm.c
> index 7d5b76478f0b..f4c204a8a379 100644
> --- a/mm/ksm.c
> +++ b/mm/ksm.c
> @@ -187,7 +187,7 @@ struct ksm_stable_node {
> /**
> * struct ksm_rmap_item - reverse mapping item for virtual addresses
> * @rmap_list: next rmap_item in mm_slot's singly-linked rmap_list
> - * @anon_vma: pointer to anon_vma for this mm,address, when in stable tree
> + * @anon_rmap: anonymous folio rmap for this mm,address, when in stable tree
> * @nid: NUMA node id of unstable tree in which linked (may not match page)
> * @mm: the memory structure this rmap_item is pointing into
> * @address: the virtual address this rmap_item tracks (+ flags in low bits)
> @@ -201,7 +201,7 @@ struct ksm_stable_node {
> struct ksm_rmap_item {
> struct ksm_rmap_item *rmap_list;
> union {
> - struct anon_vma *anon_vma; /* when stable */
> + anon_rmap_t anon_rmap; /* when stable */
> #ifdef CONFIG_NUMA
> int nid; /* when node of unstable tree */
> #endif
> @@ -786,7 +786,7 @@ static void break_cow(struct ksm_rmap_item *rmap_item)
> * It is not an accident that whenever we want to break COW
> * to undo, we also need to drop a reference to the anon_vma.
> */
> - put_anon_vma(rmap_item->anon_vma);
> + put_anon_rmap(rmap_item->anon_rmap);
>
> mmap_read_lock(mm);
> vma = find_mergeable_vma(mm, addr);
> @@ -898,7 +898,7 @@ static void remove_node_from_stable_tree(struct ksm_stable_node *stable_node)
>
> VM_BUG_ON(stable_node->rmap_hlist_len <= 0);
> stable_node->rmap_hlist_len--;
> - put_anon_vma(rmap_item->anon_vma);
> + put_anon_rmap(rmap_item->anon_rmap);
> rmap_item->address &= PAGE_MASK;
> cond_resched();
> }
> @@ -1051,7 +1051,7 @@ static void remove_rmap_item_from_tree(struct ksm_rmap_item *rmap_item)
> VM_BUG_ON(stable_node->rmap_hlist_len <= 0);
> stable_node->rmap_hlist_len--;
>
> - put_anon_vma(rmap_item->anon_vma);
> + put_anon_rmap(rmap_item->anon_rmap);
> rmap_item->head = NULL;
> rmap_item->address &= PAGE_MASK;
>
> @@ -1598,9 +1598,8 @@ static int try_to_merge_with_ksm_page(struct ksm_rmap_item *rmap_item,
> /* Unstable nid is in union with stable anon_vma: remove first */
> remove_rmap_item_from_tree(rmap_item);
>
> - /* Must get reference to anon_vma while still holding mmap_lock */
> - rmap_item->anon_vma = vma->anon_vma;
> - get_anon_vma(vma->anon_vma);
> + /* Must get reference to anon_rmap while still holding mmap_lock */
> + rmap_item->anon_rmap = vma_get_anon_rmap(vma);
> out:
> mmap_read_unlock(mm);
> trace_ksm_merge_with_ksm_page(kpage, page_to_pfn(kpage ? kpage : page),
> @@ -3108,7 +3107,6 @@ struct folio *ksm_might_need_to_copy(struct folio *folio,
> struct vm_area_struct *vma, unsigned long addr)
> {
> struct page *page = folio_page(folio, 0);
> - struct anon_vma *anon_vma = folio_anon_vma(folio);
> struct folio *new_folio;
>
> if (folio_test_large(folio))
> @@ -3118,10 +3116,10 @@ struct folio *ksm_might_need_to_copy(struct folio *folio,
> if (folio_stable_node(folio) &&
> !(ksm_run & KSM_RUN_UNMERGE))
> return folio; /* no need to copy it */
> - } else if (!anon_vma) {
> + } else if (!folio_test_anon(folio)) {
> return folio; /* no need to copy it */
> } else if (folio->index == linear_page_index(vma, addr) &&
> - anon_vma->root == vma->anon_vma->root) {
> + folio_maybe_same_anon_vma(folio, vma)) {
> return folio; /* still no need to copy it */
> }
> if (PageHWPoison(page))
> @@ -3173,20 +3171,20 @@ void rmap_walk_ksm(struct folio *folio, struct rmap_walk_control *rwc)
> hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) {
> /* Ignore the stable/unstable/sqnr flags */
> const unsigned long addr = rmap_item->address & PAGE_MASK;
> - struct anon_vma *anon_vma = rmap_item->anon_vma;
> + anon_rmap_t anon_rmap = rmap_item->anon_rmap;
> struct anon_vma_chain *vmac;
> struct vm_area_struct *vma;
>
> cond_resched();
> - if (!anon_vma_trylock_read(anon_vma)) {
> + if (!anon_rmap_trylock_read(anon_rmap)) {
> if (rwc->try_lock) {
> rwc->contended = true;
> return;
> }
> - anon_vma_lock_read(anon_vma);
> + anon_rmap_lock_read(anon_rmap);
> }
>
> - anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
> + anon_rmap_foreach_vma(vma, vmac, anon_rmap,
> 0, ULONG_MAX) {
>
> cond_resched();
> @@ -3207,15 +3205,15 @@ void rmap_walk_ksm(struct folio *folio, struct rmap_walk_control *rwc)
> continue;
>
> if (!rwc->rmap_one(folio, vma, addr, rwc->arg)) {
> - anon_vma_unlock_read(anon_vma);
> + anon_rmap_unlock_read(anon_rmap);
> return;
> }
> if (rwc->done && rwc->done(folio)) {
> - anon_vma_unlock_read(anon_vma);
> + anon_rmap_unlock_read(anon_rmap);
> return;
> }
> }
> - anon_vma_unlock_read(anon_vma);
> + anon_rmap_unlock_read(anon_rmap);
> }
> if (!search_new_forks++)
> goto again;
> @@ -3237,9 +3235,9 @@ void collect_procs_ksm(const struct folio *folio, const struct page *page,
> if (!stable_node)
> return;
> hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) {
> - struct anon_vma *av = rmap_item->anon_vma;
> + anon_rmap_t anon_rmap = rmap_item->anon_rmap;
>
> - anon_vma_lock_read(av);
> + anon_rmap_lock_read(anon_rmap);
> rcu_read_lock();
> for_each_process(tsk) {
> struct anon_vma_chain *vmac;
> @@ -3248,10 +3246,9 @@ void collect_procs_ksm(const struct folio *folio, const struct page *page,
> task_early_kill(tsk, force_early);
> if (!t)
> continue;
> - anon_vma_interval_tree_foreach(vmac, &av->rb_root, 0,
> + anon_rmap_foreach_vma(vma, vmac, anon_rmap, 0,
> ULONG_MAX)
> {
> - vma = vmac->vma;
> if (vma->vm_mm == t->mm) {
> addr = rmap_item->address & PAGE_MASK;
> add_to_kill_ksm(t, page, vma, to_kill,
> @@ -3260,7 +3257,7 @@ void collect_procs_ksm(const struct folio *folio, const struct page *page,
> }
> }
> rcu_read_unlock();
> - anon_vma_unlock_read(av);
> + anon_rmap_unlock_read(anon_rmap);
> }
> }
> #endif
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
> index ee42d4361309..bc9abba75b5d 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -547,11 +547,11 @@ static void collect_procs_anon(const struct folio *folio,
> int force_early)
> {
> struct task_struct *tsk;
> - struct anon_vma *av;
> + anon_rmap_t anon_rmap;
> pgoff_t pgoff;
>
> - av = folio_lock_anon_vma_read(folio, NULL);
> - if (av == NULL) /* Not actually mapped anymore */
> + anon_rmap = folio_lock_anon_rmap_read(folio, NULL);
> + if (!anon_rmap_value(anon_rmap)) /* Not actually mapped anymore */
> return;
>
> pgoff = page_pgoff(folio, page);
> @@ -564,9 +564,8 @@ static void collect_procs_anon(const struct folio *folio,
>
> if (!t)
> continue;
> - anon_vma_interval_tree_foreach(vmac, &av->rb_root,
> + anon_rmap_foreach_vma(vma, vmac, anon_rmap,
> pgoff, pgoff) {
> - vma = vmac->vma;
> if (vma->vm_mm != t->mm)
> continue;
> addr = page_mapped_in_vma(page, vma);
> @@ -574,7 +573,7 @@ static void collect_procs_anon(const struct folio *folio,
> }
> }
> rcu_read_unlock();
> - anon_vma_unlock_read(av);
> + anon_rmap_unlock_read(anon_rmap);
> }
>
> /*
> diff --git a/mm/migrate.c b/mm/migrate.c
> index 8a64291ab5b4..769983cf14e0 100644
> --- a/mm/migrate.c
> +++ b/mm/migrate.c
> @@ -1142,18 +1142,18 @@ enum {
>
> static void __migrate_folio_record(struct folio *dst,
> int old_page_state,
> - struct anon_vma *anon_vma)
> + anon_rmap_t anon_rmap)
> {
> - dst->private = (void *)anon_vma + old_page_state;
> + dst->private = (void *)anon_rmap_to_anon_vma(anon_rmap) + old_page_state;
> }
>
> static void __migrate_folio_extract(struct folio *dst,
> int *old_page_state,
> - struct anon_vma **anon_vmap)
> + anon_rmap_t *anon_rmapp)
> {
> unsigned long private = (unsigned long)dst->private;
>
> - *anon_vmap = (struct anon_vma *)(private & ~PAGE_OLD_STATES);
> + *anon_rmapp = anon_vma_to_anon_rmap((void *)(private & ~PAGE_OLD_STATES));
> *old_page_state = private & PAGE_OLD_STATES;
> dst->private = NULL;
> }
> @@ -1161,15 +1161,15 @@ static void __migrate_folio_extract(struct folio *dst,
> /* Restore the source folio to the original state upon failure */
> static void migrate_folio_undo_src(struct folio *src,
> int page_was_mapped,
> - struct anon_vma *anon_vma,
> + anon_rmap_t anon_rmap,
> bool locked,
> struct list_head *ret)
> {
> if (page_was_mapped)
> remove_migration_ptes(src, src, 0);
> - /* Drop an anon_vma reference if we took one */
> - if (anon_vma)
> - put_anon_vma(anon_vma);
> + /* Drop an anon_rmap reference if we took one */
> + if (anon_rmap_value(anon_rmap))
> + put_anon_rmap(anon_rmap);
> if (locked)
> folio_unlock(src);
> if (ret)
> @@ -1210,7 +1210,7 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
> struct folio *dst;
> int rc = -EAGAIN;
> int old_page_state = 0;
> - struct anon_vma *anon_vma = NULL;
> + anon_rmap_t anon_rmap = ANON_RMAP_NULL;
> bool locked = false;
> bool dst_locked = false;
>
> @@ -1275,19 +1275,19 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
> /*
> * By try_to_migrate(), src->mapcount goes down to 0 here. In this case,
> * we cannot notice that anon_vma is freed while we migrate a page.
> - * This get_anon_vma() delays freeing anon_vma pointer until the end
> + * This get_anon_rmap() delays freeing anon_rmap pointer until the end
> * of migration. File cache pages are no problem because of page_lock()
> * File Caches may use write_page() or lock_page() in migration, then,
> * just care Anon page here.
> *
> - * Only folio_get_anon_vma() understands the subtleties of
> - * getting a hold on an anon_vma from outside one of its mms.
> - * But if we cannot get anon_vma, then we won't need it anyway,
> + * Only folio_get_anon_rmap() understands the subtleties of
> + * getting a hold on an anon_rmap from outside one of its mms.
> + * But if we cannot get anon_rmap, then we won't need it anyway,
> * because that implies that the anon page is no longer mapped
> * (and cannot be remapped so long as we hold the page lock).
> */
> if (folio_test_anon(src) && !folio_test_ksm(src))
> - anon_vma = folio_get_anon_vma(src);
> + anon_rmap = folio_get_anon_rmap(src);
>
> /*
> * Block others from accessing the new page when we get around to
> @@ -1302,7 +1302,7 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
> dst_locked = true;
>
> if (unlikely(page_has_movable_ops(&src->page))) {
> - __migrate_folio_record(dst, old_page_state, anon_vma);
> + __migrate_folio_record(dst, old_page_state, anon_rmap);
> return 0;
> }
>
> @@ -1326,13 +1326,13 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
> } else if (folio_mapped(src)) {
> /* Establish migration ptes */
> VM_BUG_ON_FOLIO(folio_test_anon(src) &&
> - !folio_test_ksm(src) && !anon_vma, src);
> + !folio_test_ksm(src) && !anon_rmap_value(anon_rmap), src);
> try_to_migrate(src, mode == MIGRATE_ASYNC ? TTU_BATCH_FLUSH : 0);
> old_page_state |= PAGE_WAS_MAPPED;
> }
>
> if (!folio_mapped(src)) {
> - __migrate_folio_record(dst, old_page_state, anon_vma);
> + __migrate_folio_record(dst, old_page_state, anon_rmap);
> return 0;
> }
>
> @@ -1345,7 +1345,7 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
> ret = NULL;
>
> migrate_folio_undo_src(src, old_page_state & PAGE_WAS_MAPPED,
> - anon_vma, locked, ret);
> + anon_rmap, locked, ret);
> migrate_folio_undo_dst(dst, dst_locked, put_new_folio, private);
>
> return rc;
> @@ -1359,12 +1359,12 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
> {
> int rc;
> int old_page_state = 0;
> - struct anon_vma *anon_vma = NULL;
> + anon_rmap_t anon_rmap = ANON_RMAP_NULL;
> bool src_deferred_split = false;
> bool src_partially_mapped = false;
> struct list_head *prev;
>
> - __migrate_folio_extract(dst, &old_page_state, &anon_vma);
> + __migrate_folio_extract(dst, &old_page_state, &anon_rmap);
> prev = dst->lru.prev;
> list_del(&dst->lru);
>
> @@ -1425,9 +1425,9 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
> * and will be freed.
> */
> list_del(&src->lru);
> - /* Drop an anon_vma reference if we took one */
> - if (anon_vma)
> - put_anon_vma(anon_vma);
> + /* Drop an anon_rmap reference if we took one */
> + if (anon_rmap_value(anon_rmap))
> + put_anon_rmap(anon_rmap);
> folio_unlock(src);
> migrate_folio_done(src, reason);
>
> @@ -1439,12 +1439,12 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
> */
> if (rc == -EAGAIN) {
> list_add(&dst->lru, prev);
> - __migrate_folio_record(dst, old_page_state, anon_vma);
> + __migrate_folio_record(dst, old_page_state, anon_rmap);
> return rc;
> }
>
> migrate_folio_undo_src(src, old_page_state & PAGE_WAS_MAPPED,
> - anon_vma, true, ret);
> + anon_rmap, true, ret);
> migrate_folio_undo_dst(dst, true, put_new_folio, private);
>
> return rc;
> @@ -1476,7 +1476,7 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio,
> struct folio *dst;
> int rc = -EAGAIN;
> int page_was_mapped = 0;
> - struct anon_vma *anon_vma = NULL;
> + anon_rmap_t anon_rmap = ANON_RMAP_NULL;
> struct address_space *mapping = NULL;
> enum ttu_flags ttu = 0;
>
> @@ -1513,7 +1513,7 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio,
> }
>
> if (folio_test_anon(src))
> - anon_vma = folio_get_anon_vma(src);
> + anon_rmap = folio_get_anon_rmap(src);
>
> if (unlikely(!folio_trylock(dst)))
> goto put_anon;
> @@ -1550,8 +1550,8 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio,
> folio_unlock(dst);
>
> put_anon:
> - if (anon_vma)
> - put_anon_vma(anon_vma);
> + if (anon_rmap_value(anon_rmap))
> + put_anon_rmap(anon_rmap);
>
> if (!rc) {
> move_hugetlb_state(src, dst, reason);
> @@ -1778,11 +1778,11 @@ static void migrate_folios_undo(struct list_head *src_folios,
> dst2 = list_next_entry(dst, lru);
> list_for_each_entry_safe(folio, folio2, src_folios, lru) {
> int old_page_state = 0;
> - struct anon_vma *anon_vma = NULL;
> + anon_rmap_t anon_rmap = ANON_RMAP_NULL;
>
> - __migrate_folio_extract(dst, &old_page_state, &anon_vma);
> + __migrate_folio_extract(dst, &old_page_state, &anon_rmap);
> migrate_folio_undo_src(folio, old_page_state & PAGE_WAS_MAPPED,
> - anon_vma, true, ret_folios);
> + anon_rmap, true, ret_folios);
> list_del(&dst->lru);
> migrate_folio_undo_dst(dst, true, put_new_folio, private);
> dst = dst2;
> diff --git a/mm/page_idle.c b/mm/page_idle.c
> index 9c67cbac2965..d4103f20f526 100644
> --- a/mm/page_idle.c
> +++ b/mm/page_idle.c
> @@ -102,7 +102,7 @@ static void page_idle_clear_pte_refs(struct folio *folio)
> */
> static struct rmap_walk_control rwc = {
> .rmap_one = page_idle_clear_pte_refs_one,
> - .anon_lock = folio_lock_anon_vma_read,
> + .anon_lock = folio_lock_anon_rmap_read,
> };
>
> if (!folio_mapped(folio) || !folio_raw_mapping(folio))
> diff --git a/mm/rmap.c b/mm/rmap.c
> index 1b2dada71778..41607168e00e 100644
> --- a/mm/rmap.c
> +++ b/mm/rmap.c
> @@ -630,8 +630,8 @@ struct anon_vma *folio_get_anon_vma(const struct folio *folio)
> * reference like with folio_get_anon_vma() and then block on the mutex
> * on !rwc->try_lock case.
> */
> -struct anon_vma *folio_lock_anon_vma_read(const struct folio *folio,
> - struct rmap_walk_control *rwc)
> +static struct anon_vma *folio_lock_anon_vma_read(const struct folio *folio,
> + struct rmap_walk_control *rwc)
> {
> struct anon_vma *anon_vma = NULL;
> struct anon_vma *root_anon_vma;
> @@ -744,6 +744,14 @@ void anon_rmap_unlock_read(anon_rmap_t anon_rmap)
> anon_vma_unlock_read(anon_rmap_to_anon_vma(anon_rmap));
> }
>
> +static anon_rmap_t folio_anon_rmap(const struct folio *folio)
> +{
> + struct anon_vma *anon_vma;
> +
> + anon_vma = folio_anon_vma(folio);
> + return anon_vma ? anon_vma_to_anon_rmap(anon_vma) : ANON_RMAP_NULL;
> +}
> +
> bool folio_maybe_same_anon_vma(const struct folio *folio,
> const struct vm_area_struct *vma)
> {
> @@ -930,13 +938,11 @@ unsigned long page_address_in_vma(const struct folio *folio,
> const struct page *page, const struct vm_area_struct *vma)
> {
> if (folio_test_anon(folio)) {
> - struct anon_vma *anon_vma = folio_anon_vma(folio);
> /*
> * Note: swapoff's unuse_vma() is more efficient with this
> * check, and needs it to match anon_vma when KSM is active.
> */
> - if (!vma->anon_vma || !anon_vma ||
> - vma->anon_vma->root != anon_vma->root)
> + if (!vma->anon_vma || !folio_maybe_same_anon_vma(folio, vma))
> return -EFAULT;
> } else if (!vma->vm_file) {
> return -EFAULT;
> @@ -944,7 +950,7 @@ unsigned long page_address_in_vma(const struct folio *folio,
> return -EFAULT;
> }
>
> - /* KSM folios don't reach here because of the !anon_vma check */
> + /* The !folio_maybe_same_anon_vma() above handles KSM folios */
> return vma_address(vma, page_pgoff(folio, page), 1);
> }
>
> @@ -1145,7 +1151,7 @@ int folio_referenced(struct folio *folio, int is_locked,
> struct rmap_walk_control rwc = {
> .rmap_one = folio_referenced_one,
> .arg = (void *)&pra,
> - .anon_lock = folio_lock_anon_vma_read,
> + .anon_lock = folio_lock_anon_rmap_read,
> .try_lock = true,
> .invalid_vma = invalid_folio_referenced_vma,
> };
> @@ -1580,8 +1586,7 @@ static void __page_check_anon_rmap(const struct folio *folio,
> * are initially only visible via the pagetables, and the pte is locked
> * over the call to folio_add_new_anon_rmap.
> */
> - VM_BUG_ON_FOLIO(folio_anon_vma(folio)->root != vma->anon_vma->root,
> - folio);
> + VM_BUG_ON_FOLIO(!folio_maybe_same_anon_vma(folio, vma), folio);
> VM_BUG_ON_PAGE(page_pgoff(folio, page) != linear_page_index(vma, address),
> page);
> }
> @@ -2468,7 +2473,7 @@ void try_to_unmap(struct folio *folio, enum ttu_flags flags)
> .rmap_one = try_to_unmap_one,
> .arg = (void *)flags,
> .done = folio_not_mapped,
> - .anon_lock = folio_lock_anon_vma_read,
> + .anon_lock = folio_lock_anon_rmap_read,
> };
>
> if (flags & TTU_RMAP_LOCKED)
> @@ -2813,7 +2818,7 @@ void try_to_migrate(struct folio *folio, enum ttu_flags flags)
> .rmap_one = try_to_migrate_one,
> .arg = (void *)flags,
> .done = folio_not_mapped,
> - .anon_lock = folio_lock_anon_vma_read,
> + .anon_lock = folio_lock_anon_rmap_read,
> };
>
> /*
> @@ -2990,8 +2995,8 @@ void __put_anon_vma(struct anon_vma *anon_vma)
> anon_vma_free(root);
> }
>
> -static struct anon_vma *rmap_walk_anon_lock(const struct folio *folio,
> - struct rmap_walk_control *rwc)
> +static anon_rmap_t rmap_walk_anon_lock(const struct folio *folio,
> + struct rmap_walk_control *rwc)
> {
> struct anon_vma *anon_vma;
>
> @@ -3006,7 +3011,7 @@ static struct anon_vma *rmap_walk_anon_lock(const struct folio *folio,
> */
> anon_vma = folio_anon_vma(folio);
> if (!anon_vma)
> - return NULL;
> + return ANON_RMAP_NULL;
>
> if (anon_vma_trylock_read(anon_vma))
> goto out;
> @@ -3019,7 +3024,7 @@ static struct anon_vma *rmap_walk_anon_lock(const struct folio *folio,
>
> anon_vma_lock_read(anon_vma);
> out:
> - return anon_vma;
> + return anon_vma ? anon_vma_to_anon_rmap(anon_vma) : ANON_RMAP_NULL;
> }
>
> /*
> @@ -3035,9 +3040,10 @@ static struct anon_vma *rmap_walk_anon_lock(const struct folio *folio,
> static void rmap_walk_anon(struct folio *folio,
> struct rmap_walk_control *rwc, bool locked)
> {
> - struct anon_vma *anon_vma;
> + anon_rmap_t anon_rmap;
> pgoff_t pgoff_start, pgoff_end;
> struct anon_vma_chain *avc;
> + struct vm_area_struct *vma;
I have no idea why you put the VMA at this scope...
>
> /*
> * The folio lock ensures that folio->mapping can't be changed under us
> @@ -3046,20 +3052,19 @@ static void rmap_walk_anon(struct folio *folio,
> VM_WARN_ON_FOLIO(!folio_test_locked(folio), folio);
>
> if (locked) {
> - anon_vma = folio_anon_vma(folio);
> + anon_rmap = folio_anon_rmap(folio);
> /* anon_vma disappear under us? */
> - VM_BUG_ON_FOLIO(!anon_vma, folio);
> + VM_BUG_ON_FOLIO(!anon_rmap_value(anon_rmap), folio);
> } else {
> - anon_vma = rmap_walk_anon_lock(folio, rwc);
> + anon_rmap = rmap_walk_anon_lock(folio, rwc);
> }
> - if (!anon_vma)
> + if (!anon_rmap_value(anon_rmap))
> return;
>
> pgoff_start = folio_pgoff(folio);
> pgoff_end = pgoff_start + folio_nr_pages(folio) - 1;
> - anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root,
> + anon_rmap_foreach_vma(vma, avc, anon_rmap,
> pgoff_start, pgoff_end) {
> - struct vm_area_struct *vma = avc->vma;
Don't throw random changes like this in with a general replacement patch.
> unsigned long address = vma_address(vma, pgoff_start,
> folio_nr_pages(folio));
>
> @@ -3076,7 +3081,7 @@ static void rmap_walk_anon(struct folio *folio,
> }
>
> if (!locked)
> - anon_vma_unlock_read(anon_vma);
> + anon_rmap_unlock_read(anon_rmap);
> }
>
> /**
> --
> 2.17.1
>
next prev parent reply other threads:[~2026-05-27 11:50 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-27 11:01 [PATCH 0/15] mm: introduce ANON_VMA_LAZY for deferred anon_vma creation tao
2026-05-27 11:01 ` [PATCH 01/15] mm/rmap: introduce anon_rmap APIs for anonymous folios tao
2026-05-27 11:44 ` Lorenzo Stoakes
2026-05-27 11:01 ` [PATCH 02/15] mm: convert anon_vma rmap APIs to anon_rmap tao
2026-05-27 11:49 ` Lorenzo Stoakes [this message]
2026-05-27 11:01 ` [PATCH 03/15] mm: introduce anon_vma_tree_t for multiple anon_vma topologies tao
2026-05-27 11:56 ` Lorenzo Stoakes
2026-05-27 11:01 ` [PATCH 04/15] mm: switch to anon_vma_tree_t APIs in preparation for ANON_VMA_LAZY tao
2026-05-27 11:01 ` [PATCH 05/15] mm: add CONFIG_ANON_VMA_LAZY and folio helpers tao
2026-05-27 11:01 ` [PATCH 06/15] mm: add CONFIG_VMA_REF and VMA helpers tao
2026-05-27 11:01 ` [PATCH 07/15] mm: replace direct FOLIO_MAPPING_ANON usage with helpers tao
2026-05-27 11:01 ` [PATCH 08/15] mm: prepare rmap infrastructure for ANON_VMA_LAZY tao
2026-05-27 11:01 ` [PATCH 09/15] mm: implement ANON_VMA_LAZY rmap semantics tao
2026-05-27 11:01 ` [PATCH 10/15] mm: defer anon_vma creation with ANON_VMA_LAZY tao
2026-05-27 11:01 ` [PATCH 11/15] mm: handle ANON_VMA_LAZY in huge page operations tao
2026-05-27 11:01 ` [PATCH 12/15] mm: handle ANON_VMA_LAZY during migration tao
2026-05-27 11:01 ` [PATCH 13/15] mm: support setup and upgrade of ANON_VMA_LAZY folios tao
2026-05-27 11:01 ` [PATCH 14/15] mm: support merging of ANON_VMA_LAZY VMAs tao
2026-05-27 11:01 ` [PATCH 15/15] mm: enable CONFIG_ANON_VMA_LAZY on arm64 and x86_64 tao
2026-05-27 11:23 ` [PATCH 0/15] mm: introduce ANON_VMA_LAZY for deferred anon_vma creation Pedro Falcato
2026-05-27 11:30 ` Lorenzo Stoakes
2026-05-27 14:33 ` Lorenzo Stoakes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ahbZdWDiqTCWU77K@lucifer \
--to=ljs@kernel.org \
--cc=21cnbao@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=apopple@nvidia.com \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=bp@alien8.de \
--cc=byungchul@sk.com \
--cc=catalin.marinas@arm.com \
--cc=chengming.zhou@linux.dev \
--cc=damon@lists.linux.dev \
--cc=dave.hansen@linux.intel.com \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=dvander@google.com \
--cc=gourry@gourry.net \
--cc=harry@kernel.org \
--cc=hpa@zytor.com \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=jgg@ziepe.ca \
--cc=jhubbard@nvidia.com \
--cc=joshua.hahnjy@gmail.com \
--cc=jparsana@google.com \
--cc=kas@kernel.org \
--cc=kees@kernel.org \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=luizcap@redhat.com \
--cc=matthew.brost@intel.com \
--cc=mhocko@suse.com \
--cc=mingo@redhat.com \
--cc=nao.horiguchi@gmail.com \
--cc=npache@redhat.com \
--cc=peterx@redhat.com \
--cc=pfalcato@suse.de \
--cc=rakie.kim@sk.com \
--cc=riel@surriel.com \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=ryncsn@gmail.com \
--cc=shakeel.butt@linux.dev \
--cc=sj@kernel.org \
--cc=surenb@google.com \
--cc=tao.wangtao@honor.com \
--cc=tglx@kernel.org \
--cc=vbabka@kernel.org \
--cc=wangzicheng@honor.com \
--cc=will@kernel.org \
--cc=willy@infradead.org \
--cc=x86@kernel.org \
--cc=xu.xin16@zte.com.cn \
--cc=ying.huang@linux.alibaba.com \
--cc=zhangji1@honor.com \
--cc=zhangjiao2@cmss.chinamobile.com \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox