[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <f4e43699-b0de-4923-a798-89522857bd1f@kernel.org>
Date: Mon, 1 Dec 2025 11:19:04 +0100
From: "David Hildenbrand (Red Hat)" <david@...nel.org>
To: Gabriel Krisman Bertazi <krisman@...e.de>, linux-mm@...ck.org
Cc: linux-kernel@...r.kernel.org, jack@...e.cz,
Mateusz Guzik <mjguzik@...il.com>, Shakeel Butt <shakeel.butt@...ux.dev>,
Michal Hocko <mhocko@...nel.org>,
Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
Dennis Zhou <dennis@...nel.org>, Tejun Heo <tj@...nel.org>,
Christoph Lameter <cl@...two.org>, Andrew Morton
<akpm@...ux-foundation.org>, Lorenzo Stoakes <lorenzo.stoakes@...cle.com>,
"Liam R. Howlett" <Liam.Howlett@...cle.com>, Vlastimil Babka
<vbabka@...e.cz>, Mike Rapoport <rppt@...nel.org>,
Suren Baghdasaryan <surenb@...gle.com>
Subject: Re: [RFC PATCH 4/4] mm: Split a slow path for updating mm counters
On 11/28/25 00:36, Gabriel Krisman Bertazi wrote:
> For cases where we know we are not coming from local context, there is
> no point in touching current when incrementing/decrementing the
> counters. Split this path into another helper to avoid this cost.
>
> Signed-off-by: Gabriel Krisman Bertazi <krisman@...e.de>
> ---
> arch/s390/mm/gmap_helpers.c | 4 ++--
> arch/s390/mm/pgtable.c | 4 ++--
> fs/exec.c | 2 +-
> include/linux/mm.h | 14 +++++++++++---
> kernel/events/uprobes.c | 2 +-
> mm/filemap.c | 2 +-
> mm/huge_memory.c | 22 +++++++++++-----------
> mm/khugepaged.c | 6 +++---
> mm/ksm.c | 2 +-
> mm/madvise.c | 2 +-
> mm/memory.c | 20 ++++++++++----------
> mm/migrate.c | 2 +-
> mm/migrate_device.c | 2 +-
> mm/rmap.c | 16 ++++++++--------
> mm/swapfile.c | 6 +++---
> mm/userfaultfd.c | 2 +-
> 16 files changed, 58 insertions(+), 50 deletions(-)
>
> diff --git a/arch/s390/mm/gmap_helpers.c b/arch/s390/mm/gmap_helpers.c
> index d4c3c36855e2..6d8498c56d08 100644
> --- a/arch/s390/mm/gmap_helpers.c
> +++ b/arch/s390/mm/gmap_helpers.c
> @@ -29,9 +29,9 @@
> static void ptep_zap_swap_entry(struct mm_struct *mm, swp_entry_t entry)
> {
> if (!non_swap_entry(entry))
> - dec_mm_counter(mm, MM_SWAPENTS);
> + dec_mm_counter_other(mm, MM_SWAPENTS);
> else if (is_migration_entry(entry))
> - dec_mm_counter(mm, mm_counter(pfn_swap_entry_folio(entry)));
> + dec_mm_counter_other(mm, mm_counter(pfn_swap_entry_folio(entry)));
> free_swap_and_cache(entry);
> }
>
> diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
> index 0fde20bbc50b..021a04f958e5 100644
> --- a/arch/s390/mm/pgtable.c
> +++ b/arch/s390/mm/pgtable.c
> @@ -686,11 +686,11 @@ void ptep_unshadow_pte(struct mm_struct *mm, unsigned long saddr, pte_t *ptep)
> static void ptep_zap_swap_entry(struct mm_struct *mm, swp_entry_t entry)
> {
> if (!non_swap_entry(entry))
> - dec_mm_counter(mm, MM_SWAPENTS);
> + dec_mm_counter_other(mm, MM_SWAPENTS);
> else if (is_migration_entry(entry)) {
> struct folio *folio = pfn_swap_entry_folio(entry);
>
> - dec_mm_counter(mm, mm_counter(folio));
> + dec_mm_counter_other(mm, mm_counter(folio));
> }
> free_swap_and_cache(entry);
> }
> diff --git a/fs/exec.c b/fs/exec.c
> index 4298e7e08d5d..33d0eb00d315 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -137,7 +137,7 @@ static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
> return;
>
> bprm->vma_pages = pages;
> - add_mm_counter(mm, MM_ANONPAGES, diff);
> + add_mm_counter_local(mm, MM_ANONPAGES, diff);
> }
>
> static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 29de4c60ac6c..2db12280e938 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2689,7 +2689,7 @@ static inline unsigned long get_mm_counter_sum(struct mm_struct *mm, int member)
>
> void mm_trace_rss_stat(struct mm_struct *mm, int member);
>
> -static inline void add_mm_counter(struct mm_struct *mm, int member, long value)
> +static inline void add_mm_counter_local(struct mm_struct *mm, int member, long value)
> {
> if (READ_ONCE(current->mm) == mm)
> lazy_percpu_counter_add_fast(&mm->rss_stat[member], value);
> @@ -2698,9 +2698,17 @@ static inline void add_mm_counter(struct mm_struct *mm, int member, long value)
>
> mm_trace_rss_stat(mm, member);
> }
> +static inline void add_mm_counter_other(struct mm_struct *mm, int member, long value)
> +{
> + lazy_percpu_counter_add_atomic(&mm->rss_stat[member], value);
> +
> + mm_trace_rss_stat(mm, member);
> +}
>
> -#define inc_mm_counter(mm, member) add_mm_counter(mm, member, 1)
> -#define dec_mm_counter(mm, member) add_mm_counter(mm, member, -1)
> +#define inc_mm_counter_local(mm, member) add_mm_counter_local(mm, member, 1)
> +#define dec_mm_counter_local(mm, member) add_mm_counter_local(mm, member, -1)
> +#define inc_mm_counter_other(mm, member) add_mm_counter_other(mm, member, 1)
> +#define dec_mm_counter_other(mm, member) add_mm_counter_other(mm, member, -1)
I'd have thought that there is a local and !local version, whereby the
latter one would simply maintain the old name. The "_other()" sticks out
a bit.
E.g., cmpxch() vs. cmpxchg_local().
Or would "_remote()" better describe what "_other()" intends to do?
--
Cheers
David
Powered by blists - more mailing lists