All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: tao <tao.wangtao@honor.com>
Cc: damon@lists.linux.dev
Subject: Re: [PATCH 01/15] mm/rmap: introduce anon_rmap APIs for anonymous folios
Date: Wed, 27 May 2026 11:32:21 +0000	[thread overview]
Message-ID: <20260527113222.3B2AF1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260527110147.17815-2-tao.wangtao@honor.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Lockless reads of anon_vma->root in folio_maybe_same_anon_vma() lack READ_ONCE(), causing data races.
- [High] The anon_rmap_t API lacks a NULL validation helper and its cleanup/lock functions crash on ANON_RMAP_NULL.
- [Medium] vma_get_anon_rmap() incorrectly uses mmap_assert_locked(vma->vm_mm) instead of vma_assert_locked(vma).
- [Medium] The anon_rmap_foreach_vma macro evaluates the anon_rmap argument multiple times, creating an API hazard.
--

commit d698495fb94a40d2764331cdf26a351a9f9a97a3
Author: tao <tao.wangtao@honor.com>

mm/rmap: introduce anon_rmap APIs for anonymous folios
    
This patch adds a set of anon_rmap APIs to operate on the reverse mappings
of anonymous folios. It introduces anon_rmap_for_each_vma() as a wrapper
around the interval tree to prepare for RCU-based lockless rmap traversal.

> diff --git a/include/linux/rmap.h b/include/linux/rmap.h
> index 8dc0871e5f001..c42314ea43622 100644
> --- a/include/linux/rmap.h
> +++ b/include/linux/rmap.h
[ ... ]
> @@ -969,6 +1007,36 @@ 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);
> +anon_rmap_t folio_get_anon_rmap(const struct folio *folio);
> +anon_rmap_t folio_lock_anon_rmap_read(const struct folio *folio,
> +	struct rmap_walk_control *rwc);
> +
> +static inline struct vm_area_struct *anon_rmap_iter_first_vma(
> +	anon_rmap_t anon_rmap, unsigned long start, unsigned long last,
> +	struct anon_vma_chain **avc)
> +{
> +	struct anon_vma *anon_vma = anon_rmap_to_anon_vma(anon_rmap);
> +
> +	*avc = anon_vma_interval_tree_iter_first(&anon_vma->rb_root, start, last);
> +	return *avc ? (*avc)->vma : NULL;
> +}
> +
> +static inline struct vm_area_struct *anon_rmap_iter_next_vma(
> +	anon_rmap_t anon_rmap, unsigned long start, unsigned long last,
> +	struct anon_vma_chain **avc)
> +{
> +	if (!*avc)
> +		return NULL;
> +	*avc = anon_vma_interval_tree_iter_next(*avc, start, last);
> +	return *avc ? (*avc)->vma : NULL;
> +}
> +
> +#define anon_rmap_foreach_vma(vma, avc, anon_rmap, start, last) 	   \
> +	for (vma = anon_rmap_iter_first_vma(anon_rmap, start, last, &avc); \
> +	     vma; vma = anon_rmap_iter_next_vma(anon_rmap, start, last, &avc))

[Severity: Medium]
Can this macro cause unintended side effects if a caller passes an expression
like folio_get_anon_rmap(folio) as the anon_rmap argument?

It appears the argument is evaluated on every single loop iteration in the
update step, which could result in repeatedly executing any side effects.

Should the anon_rmap parameter be removed from the anon_rmap_iter_next_vma
call, as it seems to be unused there?

> +
>  #else	/* !CONFIG_MMU */
>  
>  #define anon_vma_init()		do {} while (0)
> diff --git a/mm/rmap.c b/mm/rmap.c
> index 99e1b3dc390b7..bbfd08ffae3db 100644
> --- a/mm/rmap.c
> +++ b/mm/rmap.c
> @@ -701,6 +701,79 @@ struct anon_vma *folio_lock_anon_vma_read(const struct folio *folio,
>  	return anon_vma;
>  }
>  
> +anon_rmap_t vma_get_anon_rmap(struct vm_area_struct *vma)
> +{
> +	mmap_assert_locked(vma->vm_mm);

[Severity: Medium]
Will this trigger a lockdep warning or BUG if reached from a per-VMA locked
path?

Since this API is intended for generic anonymous rmap operations, should it
use vma_assert_locked(vma) instead to properly support per-VMA locking?

> +	VM_BUG_ON(!vma->anon_vma);
> +	get_anon_vma(vma->anon_vma);
> +	return anon_vma_to_anon_rmap(vma->anon_vma);
> +}
> +
> +void put_anon_rmap(anon_rmap_t anon_rmap)
> +{
> +	put_anon_vma(anon_rmap_to_anon_vma(anon_rmap));
> +}

[Severity: High]
What happens if a caller passes ANON_RMAP_NULL to this function, or to the
locking functions like anon_rmap_lock_write()?

Since ANON_RMAP_NULL resolves to a NULL pointer, passing it to put_anon_vma()
or anon_vma_lock_write() would immediately trigger a NULL pointer dereference.

Because anon_rmap_t is a struct, standard C idioms like if (!rmap) cannot be
used to check for errors.

Would it make sense to provide an anon_rmap_valid() helper and handle NULL
handles explicitly in these paths?

[ ... ]
> +void anon_rmap_unlock_read(anon_rmap_t anon_rmap)
> +{
> +	anon_vma_unlock_read(anon_rmap_to_anon_vma(anon_rmap));
> +}
> +
> +bool folio_maybe_same_anon_vma(const struct folio *folio,
> +	const struct vm_area_struct *vma)
> +{
> +	struct anon_vma *anon_vma;
> +	struct anon_vma *tgt_anon_vma = vma->anon_vma;
> +	bool same = false;
> +
> +	rcu_read_lock();
> +	anon_vma = folio_anon_vma(folio);
> +	if (anon_vma && tgt_anon_vma)
> +		same = anon_vma->root == tgt_anon_vma->root;

[Severity: High]
Does this lockless read of anon_vma->root need to use READ_ONCE()?

Because anon_vma = folio_anon_vma(folio) is called under rcu_read_lock()
without incrementing the refcount, and anon_vma objects are allocated with
SLAB_TYPESAFE_BY_RCU, could the object be freed and recycled?

A plain C read of anon_vma->root might race with concurrent initializations of
the recycled object.

> +	rcu_read_unlock();
> +	return same;
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260527110147.17815-1-tao.wangtao@honor.com?part=1

  reply	other threads:[~2026-05-27 11:32 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 [this message]
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
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=20260527113222.3B2AF1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=damon@lists.linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=tao.wangtao@honor.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.