All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
To: Suren Baghdasaryan <surenb@google.com>
Cc: akpm@linux-foundation.org, liam@infradead.org, vbabka@kernel.org,
	 david@redhat.com, willy@infradead.org, jannh@google.com,
	paulmck@kernel.org,  pfalcato@suse.de, xueyuan.chen21@gmail.com,
	linux-mm@kvack.org,  linux-kernel@vger.kernel.org,
	linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v3 3/7] proc/task_mmu: clarify shmem mapping walk conditions in smap_gather_stats()
Date: Fri, 11 Sep 2026 17:28:14 +0100	[thread overview]
Message-ID: <aqQoPTTUC9M5HkYb@gremlin> (raw)
In-Reply-To: <20260910234737.1340642-4-surenb@google.com>

On Thu, Sep 10, 2026 at 04:47:33PM -0700, Suren Baghdasaryan wrote:
> smap_gather_stats() optimizes stats gathering by skipping the walk for
> shmem mappings in certain conditions. Update the comment to clarify
> these conditions and use vma_is_cow_mapping() for COW identification
> instead of open-coding it.
> Instead of using (start != 0) condition to identify partial walks, use
> more semantically correct (start > vma->vm_start) check.

I don't agree what you're doing is semantically correct, it's a hack really.

Callers are passing start=0 to indicate that the entire VMA should be
processed and that happens to fulfil your criteria but in a surprising way.

And the start in these cases is corrupted.

>
> No functional change intended.
>
> Suggested by: David Hildenbrand (Arm) <david@kernel.org>
> Signed-off-by: Suren Baghdasaryan <surenb@google.com>
> ---
>  fs/proc/task_mmu.c | 24 ++++++++++--------------
>  1 file changed, 10 insertions(+), 14 deletions(-)
>
> diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
> index cfc7af1b551d..3c40c9cbb9c9 100644
> --- a/fs/proc/task_mmu.c
> +++ b/fs/proc/task_mmu.c
> @@ -1257,6 +1257,7 @@ static void smap_gather_stats(struct proc_maps_private *priv,
>  			      struct mem_size_stats *mss, unsigned long start)
>  {
>  	const struct mm_walk_ops *ops = get_smaps_walk_ops(priv);
> +	const bool is_partial = start > vma->vm_start;

Yeah not in love with this, without changing how it's called.

If you're reworking it all already, the actually semantically correct thing
I think would be to do something like:

static void smap_gather_stats_range(struct proc_maps_private *priv,
		struct vm_area_struct *vma, struct mem_size_stats *mss,
		unsigned long start)
{
	...
}

Then to drop a parameter in smap_gather_stats() like:

static void smap_gather_stats_range(struct proc_maps_private *priv,
		struct vm_area_struct *vma, struct mem_size_stats *mss)
{
	smap_gather_stats_range(priv, vma, mss, vma->vm_start);
}

And then you remove the hack and make is_partial not be accidentally true for an
invalid start parameter.

>
>  	/* Invalid start */
>  	if (start >= vma->vm_end)
> @@ -1270,23 +1271,18 @@ static void smap_gather_stats(struct proc_maps_private *priv,
>
>  	if (vma->vm_file && shmem_mapping(vma->vm_file->f_mapping)) {
>  		/*
> -		 * For shared or readonly shmem mappings we know that all
> -		 * swapped out pages belong to the shmem object, and we can
> -		 * obtain the swap value much more efficiently. For private
> -		 * writable mappings, we might have COW pages that are
> -		 * not affected by the parent swapped out pages of the shmem
> -		 * object, so we have to distinguish them during the page walk.
> -		 * Unless we know that the shmem object (or the part mapped by
> -		 * our VMA) has no swapped out pages at all.
> +		 * CoW mappings might map anon folios that do not belong to
> +		 * shmem. Perform a less efficient page table walk in this
> +		 * situation, unless we know that the shmem object (or the
> +		 * part mapped by our VMA) has no swapped out pages at all.
>  		 */
> -		unsigned long shmem_swapped = shmem_swap_usage(vma);
> +		const unsigned long shmem_swapped = shmem_swap_usage(vma);
> +		const bool is_cow = vma_is_cow_mapping(vma);

Nice to see this helper naturally slot in to new stuff :)

>
> -		if (!start && (!shmem_swapped || (vma->vm_flags & VM_SHARED) ||
> -					!(vma->vm_flags & VM_WRITE))) {
> -			mss->swap += shmem_swapped;
> -		} else {
> +		if (is_partial || (shmem_swapped && is_cow))
>  			ops = get_smaps_shmem_walk_ops(priv);
> -		}
> +		else
> +			mss->swap += shmem_swapped;
>  	}
>
>  	if (!start)

Also not absolutely in love with the fact you only use is_partial above and
leave:

	if (!start)
		walk_page_vma(vma, ops, mss);
	else
		walk_page_range(vma->vm_mm, start, vma->vm_end, ops, mss);

As-is.

Should be:

	if (is_partial)
		walk_page_range(vma->vm_mm, start, vma->vm_end, ops, mss);
	else
		walk_page_vma(vma, ops, mss);

But I also wonder whether, with start not being corrupted (!) you could
just replace this with:

	walk_page_range_vma(vma, start, vma->vm_end, ops, mss);

Looking at the pagewalk.c implementations I don't know why
walk_page_range_vma() doesn't just forward [vma->vm_start, vma->vm_end) to
walk_page_range_vma()... but that's another thing :)

> --
> 2.55.0.1007.g17ff1f9808-goog
>

--
Cheers, Lorenzo

  parent reply	other threads:[~2026-09-11 16:28 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-10 23:47 [PATCH v3 0/7] read proc/pid/smaps_rollup under per-vma lock Suren Baghdasaryan
2026-09-10 23:47 ` [PATCH v3 1/7] proc/task_mmu: remove unnecessary helpers Suren Baghdasaryan
2026-09-11 10:52   ` David Hildenbrand (Arm)
2026-09-11 14:28     ` Suren Baghdasaryan
2026-09-11 14:57       ` David Hildenbrand (Arm)
2026-09-11 15:20         ` Suren Baghdasaryan
2026-09-10 23:47 ` [PATCH v3 2/7] proc/task_mmu: remove unnecessary inlines in function definitions Suren Baghdasaryan
2026-09-11 15:33   ` David Hildenbrand (Arm)
2026-09-10 23:47 ` [PATCH v3 3/7] proc/task_mmu: clarify shmem mapping walk conditions in smap_gather_stats() Suren Baghdasaryan
2026-09-11 15:33   ` David Hildenbrand (Arm)
2026-09-11 16:28   ` Lorenzo Stoakes (ARM) [this message]
2026-09-11 16:58     ` Suren Baghdasaryan
2026-09-11 17:10       ` Lorenzo Stoakes (ARM)
2026-09-11 17:39         ` Suren Baghdasaryan
2026-09-11 17:52           ` David Hildenbrand (Arm)
2026-09-11 17:56           ` Lorenzo Stoakes (ARM)
2026-09-11 18:08             ` Suren Baghdasaryan
2026-09-10 23:47 ` [PATCH v3 4/7] proc/task_mmu: remove special-casing of smap_gather_stats() start parameter Suren Baghdasaryan
2026-09-11 15:34   ` David Hildenbrand (Arm)
2026-09-11 16:39   ` Lorenzo Stoakes (ARM)
2026-09-11 17:07     ` Suren Baghdasaryan
2026-09-11 17:49       ` Lorenzo Stoakes (ARM)
2026-09-11 18:06         ` Suren Baghdasaryan
2026-09-11 18:11           ` Lorenzo Stoakes (ARM)
2026-09-11 18:15             ` Suren Baghdasaryan
2026-09-10 23:47 ` [PATCH v3 5/7] proc/task_mmu: change proc_get_vma() to stop returning gate VMA at the end Suren Baghdasaryan
2026-09-11 15:35   ` David Hildenbrand (Arm)
2026-09-11 18:26   ` Lorenzo Stoakes (ARM)
2026-09-11 18:39     ` Suren Baghdasaryan
2026-09-11 19:03     ` Lorenzo Stoakes (ARM)
2026-09-11 19:11       ` Suren Baghdasaryan
2026-09-11 19:13         ` Lorenzo Stoakes (ARM)
2026-09-11 19:18           ` Suren Baghdasaryan
2026-09-11 19:26             ` Lorenzo Stoakes (ARM)
2026-09-11 19:44               ` Suren Baghdasaryan
2026-09-11 19:45                 ` Suren Baghdasaryan
2026-09-10 23:47 ` [PATCH v3 6/7] proc/task_mmu: read proc/pid/smaps_rollup under per-vma lock Suren Baghdasaryan
2026-09-11 19:07   ` Lorenzo Stoakes (ARM)
2026-09-10 23:47 ` [PATCH v3 7/7] selftests/proc: add /proc/pid/smaps_rollup tearing tests Suren Baghdasaryan
2026-09-11 19:12   ` Lorenzo Stoakes (ARM)

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=aqQoPTTUC9M5HkYb@gremlin \
    --to=ljs@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=david@redhat.com \
    --cc=jannh@google.com \
    --cc=liam@infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=paulmck@kernel.org \
    --cc=pfalcato@suse.de \
    --cc=surenb@google.com \
    --cc=vbabka@kernel.org \
    --cc=willy@infradead.org \
    --cc=xueyuan.chen21@gmail.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.