From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: "David Hildenbrand (Arm)" <david@kernel.org>
Cc: linux-kernel@vger.kernel.org,
"Paul E. McKenney" <paulmck@kernel.org>,
Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Dennis Zhou <dennis@kernel.org>, Tejun Heo <tj@kernel.org>,
Christoph Lameter <cl@gentwo.org>,
Martin Liu <liumartin@google.com>,
David Rientjes <rientjes@google.com>,
christian.koenig@amd.com, Shakeel Butt <shakeel.butt@linux.dev>,
SeongJae Park <sj@kernel.org>, Michal Hocko <mhocko@suse.com>,
Johannes Weiner <hannes@cmpxchg.org>,
Sweet Tea Dorminy <sweettea-kernel@dorminy.me>,
Lorenzo Stoakes <ljs@kernel.org>,
"Liam R. Howlett" <liam@infradead.org>,
Mike Rapoport <rppt@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Vlastimil Babka <vbabka@kernel.org>,
Christian Brauner <brauner@kernel.org>,
Wei Yang <richard.weiyang@gmail.com>,
Miaohe Lin <linmiaohe@huawei.com>,
Al Viro <viro@zeniv.linux.org.uk>, Yu Zhao <yuzhao@google.com>,
Roman Gushchin <roman.gushchin@linux.dev>,
Mateusz Guzik <mjguzik@gmail.com>,
Matthew Wilcox <willy@infradead.org>,
Baolin Wang <baolin.wang@linux.alibaba.com>,
Aboorva Devarajan <aboorvad@linux.ibm.com>,
David Carlier <devnexen@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
linux-mm@kvack.org, Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Randy Dunlap <rdunlap@infradead.org>,
linux-doc@vger.kernel.org, Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Juri Lelli <juri.lelli@redhat.com>,
Vincent Guittot <vincent.guittot@linaro.org>,
Dietmar Eggemann <dietmar.eggemann@arm.com>,
Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
Valentin Schneider <vschneid@redhat.com>,
K Prateek Nayak <kprateek.nayak@amd.com>,
Kees Cook <kees@kernel.org>,
linux-trace-kernel@vger.kernel.org, Jan Kara <jack@suse.cz>,
linux-fsdevel@vger.kernel.org, Oleg Nesterov <oleg@redhat.com>
Subject: Re: [RFC PATCH v24 00/10] Hierarchical Percpu Counters for RSS
Date: Tue, 10 Nov 2026 20:47:05 -0500 [thread overview]
Message-ID: <93c7bb90-a671-4769-ab4b-8c16c195e22b@efficios.com> (raw)
In-Reply-To: <88a96126-11be-41cc-ab0d-372d32189e79@kernel.org>
Subject: Re: [RFC PATCH v24 00/10] Hierarchical Percpu Counters for RSS
In-Reply-To: <88a96126-11be-41cc-ab0d-372d32189e79@kernel.org>
On 2026-11-09 15:35, David Hildenbrand (Arm) wrote:
> On 11/5/26 21:36, Mathieu Desnoyers wrote:
[...]
> I think we discussed other possible applications (IIRC Michal expressed concern
> if a single user is sufficient motivation for these additional LOC). Did
> anything result from that discussion that is relevant to v24?
Yes. The next round adds a second user: the tmpfs size limit (the size=
mount option).
Today, each page charged to a tmpfs mount checks a struct percpu_counter
with percpu_counter_limited_add(). That check takes no lock only while
the mount is more than batch * nr_cpus pages below its size. At 384
CPUs, this is 1.1 GB. A smaller mount, such as a 64 MB /dev/shm, takes
the counter spinlock and sums all CPUs on every page.
The next round adds a limit counter built on the tree. It keeps the
limit strict, without a lock. fallocate() of one page at a time on a
64 MB mount, in a 384-vCPU guest, in thousands of calls per second:
processes before after
1 209 481
384 124 53944
Mounts of 2 GB and above lose 1 to 2% with 384 processes. These are
patches 8 and 9 of the next round, right after the RSS patches.
A later follow-up would use the comparison functions for the OOM killer
task selection.
[...]
>> Since commit f1a7941243c1 ("mm: convert mm's rss stats into
>> percpu_counter"), the RSS counters are struct percpu_counter with a
>> batch size of max(32, 2 * nr_cpus): their approximation error grows with
>> O(nr_cpus^2), up to 1.1GB per counter at 384 logical CPUs.
>
> Okay, so that's a per-MM problem, not a per-system problem. On a large system
> with many CPUs I'd have said "likel we don't care" :)
Right. The error is per process, so a large system does not make it
small compared to the process.
>> /proc/PID/status, /proc/PID/statm and the OOM killer moved to precise
>> sums (commits 82241a83cd15 and 5898aa8f9a0b), but the other readers
>> still use the approximation: the RSS high watermark (VmHWM, the
>> ru_maxrss reported as "Maximum resident set size" by /usr/bin/time -v,
>> taskstats), /proc/PID/stat (ps, top, monitoring agents), the taskstats
>> RSS-time integral (coremem, sampled at each tick), NUMA balancing and
>> the mark_victim tracepoint. On the test machine below, the
>> /proc/PID/stat RSS of a test process was off by 17MB while
>> single-threaded, and by up to 134MB with 64 threads.
>
> What's the resulting impact of that (temporary) imprecision?
It depends on the reader:
- The high watermark keeps it. update_hiwater_rss() stores the maximum
of the approximation, so a temporary overshoot stays in VmHWM and
ru_maxrss. /usr/bin/time -v and taskstats report that value.
- The taskstats coremem integral adds the approximate RSS at each tick,
so the error accumulates.
- /proc/PID/stat shows it as is to ps, top and monitoring agents. In
testing at 384 CPUs, it was off by 17 MB for a single-threaded
process, and by up to 134 MB with 64 threads.
- NUMA balancing makes its decisions on it.
>> Precise sums cannot fix the high watermark or the RSS-time integral:
>> update_hiwater_rss() samples the RSS on every unmap path, and the
>
> As a side-note, I absolutely hate update_hiwater_rss() on the unmap path.
:) It is also why a precise sum is not an option there.
[...]
>> Patches 1 to 5 replace struct percpu_counter for the RSS counters with
>> hierarchical per-cpu counters: per-cpu bytes carry into a tree of atomic
>> counters shaped at boot from nr_cpu_ids, with a fixed batch of 32, an
>> error bound in O(n*log(n)) and no global lock.
>
> How does this interact with CPU hotplug?
Like the per-cpu data of struct percpu_counter, the tree is shaped at
boot from nr_cpu_ids. It is not reshaped on hotplug. The residual of an
offline CPU stays in place. The precise sum still reads it, and the
bound still holds. Patch 1 has a "CPU hotplug" section on this.
[...]
>> Patches 6 and 7 keep the RSS counters of single-threaded processes exact
>> and without per-cpu memory: until a second thread shares the mm, the
>> task running on the mm adds to the bias of each counter without atomic
>> instructions, and other tasks add to its atomic bias, both read in O(1).
[...]
>
> What was the particular reason to special-case single-threaded apps? Do we
> expect them in practice to really be that RSS heavy+dynamic such that it would
> matter?
The main reason is the cost of creating a process, more than accuracy.
Every exec creates a new mm. Upstream allocates per-cpu memory for its
RSS counters there, under the per-cpu allocator mutex. It also sums all
CPUs when the mm goes away. Most processes are single-threaded and
never need this per-cpu memory.
With 64 processes spawning a static program on a 384-CPU host, 19% of
the CPU time goes to these allocations and sums. Here is posix_spawn()
of a static program which exits, in a 384-vCPU guest. The gain is over
patches 1 to 5, to isolate the single-threaded mode, as the median of 3
to 5 runs:
processes gain
1 +22%
16 +26%
64 +42%
384 +22%
In UnixBench with one copy, Process Creation gains 15%, Execl Throughput
4% and Shell Scripts 6 to 9% (one sample each). With 384 copies, the
results are within 5% of upstream, in both directions. A kernel build at
-j384 does not change.
It also saves memory: at 384 CPUs, a single-threaded mm uses 1928 bytes
instead of 8072. And a zeroed counter is a valid counter in this mode,
so a static mm such as init_mm has working RSS counters without setup.
>> Patches 8 to 10 are the tools to tune the tree shape on other hardware:
>> the percpu_counter_tree.arity= and rss_stat_batch= boot parameters, and
>> a KUnit benchmark. The default shapes were measured on one machine,
>> with up to 384 logical CPUs, so results from other hardware are welcome.
>
> Hm, so that means one might have to fine tune these toggles to get the best
> performance? That's a bit unfortunate.
They are not meant to be needed. The tree shape is chosen at boot from
nr_cpu_ids, and the RSS batch size is fixed. The parameters and the
benchmark are there to check these defaults on other hardware, because
I only measured them on one machine.
[...]
>> 1. Is mm->rss_owner acceptable, or would you prefer current->mm == mm
>> (without PF_KTHREAD) and an "activated" flag?
>
> I'm afraid I'm the wrong person to ask that question. I'd have to look into the
> details. If it's just a simple member, we likely don't care about the addition
> memory footprint (if that's your main concern).
OK, thanks.
[...]
>> 4. Should the rss_stat tracepoint report the approximation, stay
>> precise, or report both?
>
> No strong optinion on that. Do we know who uses these and for which purpose?
It was added for Android, to track the RSS of each process and detect
memory spikes: commit b3d1411b6726 ("mm: emit tracepoint when RSS
changes"). As far as I know, Perfetto reads it. Martin, would the
approximation be fine for your use?
>> 5. Should the tuning tools be merged, built only with the benchmark
>> config, or dropped later? Who could run them on non-AMD, 4-socket,
>> arm64 or POWER machines?
>
> Is there some way to have it be an auto-tuning instead of requiring this tooling?
The defaults are already automatic: the tree shape only depends on
nr_cpu_ids. A finer heuristic could use the cache topology. I would
rather get results from other hardware first, to see whether the
defaults need it.
>> 6. Is tools/testing/hpcc the right home for the topology test?
> Good question, I'd assume so.
OK, it stays there.
Thanks,
Mathieu
prev parent reply other threads:[~2026-11-11 1:47 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 20:36 Mathieu Desnoyers
2026-11-05 20:36 ` [RFC PATCH v24 01/10] lib: introduce hierarchical per-cpu counters Mathieu Desnoyers
2026-11-05 20:36 ` [RFC PATCH v24 02/10] lib: test " Mathieu Desnoyers
2026-11-05 20:36 ` [RFC PATCH v24 03/10] mm: use hierarchical per-cpu counters for the RSS counters Mathieu Desnoyers
2026-11-05 20:36 ` [RFC PATCH v24 04/10] tools/testing/hpcc: add userspace test of hierarchical per-CPU counters Mathieu Desnoyers
2026-11-05 20:36 ` [RFC PATCH v24 05/10] mm: report the approximate RSS in the rss_stat tracepoint Mathieu Desnoyers
2026-11-05 20:36 ` [RFC PATCH v24 06/10] lib: percpu_counter_tree: add lazy tree activation Mathieu Desnoyers
2026-11-05 20:36 ` [RFC PATCH v24 07/10] mm: keep the RSS counters of single-threaded processes exact Mathieu Desnoyers
2026-11-05 20:36 ` [RFC PATCH v24 08/10] lib: percpu_counter_tree: add the arity boot parameter Mathieu Desnoyers
2026-11-05 20:36 ` [RFC PATCH v24 09/10] mm: add the rss_stat_batch " Mathieu Desnoyers
2026-11-05 20:36 ` [RFC PATCH v24 10/10] lib: add a benchmark of hierarchical per-cpu counters Mathieu Desnoyers
2026-11-09 20:35 ` [RFC PATCH v24 00/10] Hierarchical Percpu Counters for RSS David Hildenbrand (Arm)
2026-11-11 1:47 ` Mathieu Desnoyers [this message]
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=93c7bb90-a671-4769-ab4b-8c16c195e22b@efficios.com \
--to=mathieu.desnoyers@efficios.com \
--cc=aboorvad@linux.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=brauner@kernel.org \
--cc=bsegall@google.com \
--cc=christian.koenig@amd.com \
--cc=cl@gentwo.org \
--cc=corbet@lwn.net \
--cc=david@kernel.org \
--cc=dennis@kernel.org \
--cc=devnexen@gmail.com \
--cc=dietmar.eggemann@arm.com \
--cc=hannes@cmpxchg.org \
--cc=jack@suse.cz \
--cc=juri.lelli@redhat.com \
--cc=kees@kernel.org \
--cc=kprateek.nayak@amd.com \
--cc=liam@infradead.org \
--cc=linmiaohe@huawei.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=liumartin@google.com \
--cc=ljs@kernel.org \
--cc=mgorman@suse.de \
--cc=mhiramat@kernel.org \
--cc=mhocko@suse.com \
--cc=mingo@redhat.com \
--cc=mjguzik@gmail.com \
--cc=oleg@redhat.com \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=rdunlap@infradead.org \
--cc=richard.weiyang@gmail.com \
--cc=rientjes@google.com \
--cc=roman.gushchin@linux.dev \
--cc=rostedt@goodmis.org \
--cc=rppt@kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=sj@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=surenb@google.com \
--cc=sweettea-kernel@dorminy.me \
--cc=tj@kernel.org \
--cc=vbabka@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=viro@zeniv.linux.org.uk \
--cc=vschneid@redhat.com \
--cc=willy@infradead.org \
--cc=yuzhao@google.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
all inboxes | Powered by JetHome®