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: 82+ 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:32 ` sashiko-bot
2026-05-27 11:44 ` Lorenzo Stoakes
2026-05-28 7:47 ` wangtao
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-28 8:55 ` wangtao
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-28 9:00 ` wangtao
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:53 ` sashiko-bot
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:42 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 07/15] mm: replace direct FOLIO_MAPPING_ANON usage with helpers tao
2026-05-27 11:43 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 08/15] mm: prepare rmap infrastructure for ANON_VMA_LAZY tao
2026-05-27 14:01 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 09/15] mm: implement ANON_VMA_LAZY rmap semantics tao
2026-05-27 12:15 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 10/15] mm: defer anon_vma creation with ANON_VMA_LAZY tao
2026-05-27 12:29 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 11/15] mm: handle ANON_VMA_LAZY in huge page operations tao
2026-05-27 12:21 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 12/15] mm: handle ANON_VMA_LAZY during migration tao
2026-05-27 12:23 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 13/15] mm: support setup and upgrade of ANON_VMA_LAZY folios tao
2026-05-27 13:02 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 14/15] mm: support merging of ANON_VMA_LAZY VMAs tao
2026-05-27 12:49 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 15/15] mm: enable CONFIG_ANON_VMA_LAZY on arm64 and x86_64 tao
2026-05-27 17:19 ` sashiko-bot
2026-05-27 11:23 ` [PATCH 0/15] mm: introduce ANON_VMA_LAZY for deferred anon_vma creation Pedro Falcato
2026-05-28 6:45 ` wangtao
2026-05-28 7:14 ` Lorenzo Stoakes
2026-05-27 11:30 ` Lorenzo Stoakes
2026-05-28 7:11 ` wangtao
2026-05-28 7:22 ` Lorenzo Stoakes
2026-05-27 14:33 ` Lorenzo Stoakes
2026-05-28 7:57 ` wangtao
2026-05-28 8:14 ` Lorenzo Stoakes
2026-05-28 23:31 ` Barry Song
2026-05-29 2:20 ` wangzicheng
2026-05-29 6:56 ` Lorenzo Stoakes
2026-05-29 6:45 ` Lorenzo Stoakes
2026-05-29 9:41 ` wangtao
2026-05-29 12:03 ` Lorenzo Stoakes
2026-06-01 1:46 ` wangtao
2026-06-02 2:15 ` Barry Song
2026-06-02 2:46 ` Lance Yang
2026-06-02 15:37 ` Lorenzo Stoakes
2026-06-02 19:44 ` Pedro Falcato
2026-06-02 23:03 ` Barry Song
2026-06-03 7:07 ` Lorenzo Stoakes
2026-06-02 19:56 ` Harry Yoo
2026-06-02 22:27 ` Barry Song
2026-06-02 20:47 ` Lorenzo Stoakes
2026-05-29 15:07 ` Jonathan Corbet
2026-05-29 15:40 ` Lorenzo Stoakes
2026-05-30 11:28 ` Barry Song
2026-06-02 16:07 ` Harry Yoo
2026-06-03 2:59 ` wangtao
2026-06-03 3:12 ` wangtao
2026-06-03 7:54 ` Lorenzo Stoakes
2026-06-03 11:05 ` wangtao
2026-06-03 11:53 ` Lorenzo Stoakes
2026-06-04 3:50 ` wangtao
2026-06-03 20:25 ` David Hildenbrand (Arm)
2026-06-03 22:14 ` Barry Song
2026-06-04 4:03 ` wangtao
2026-06-04 4:20 ` Barry Song
2026-06-04 7:35 ` wangtao
2026-06-09 15:26 ` Suren Baghdasaryan
2026-06-09 15:49 ` David Hildenbrand (Arm)
2026-06-04 3:10 ` xu.xin16
2026-06-04 4:10 ` wangtao
2026-06-05 9:38 ` David Hildenbrand (Arm)
2026-06-05 10:07 ` Lorenzo Stoakes
2026-06-05 10:56 ` David Hildenbrand (Arm)
2026-06-04 9:40 ` 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.