* [PATCH v6 00/14] Nesting support for lazy MMU mode
@ 2025-12-15 15:03 Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 01/14] powerpc/64s: Do not re-activate batched TLB flush Kevin Brodsky
` (14 more replies)
0 siblings, 15 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
When the lazy MMU mode was introduced eons ago, it wasn't made clear
whether such a sequence was legal:
arch_enter_lazy_mmu_mode()
...
arch_enter_lazy_mmu_mode()
...
arch_leave_lazy_mmu_mode()
...
arch_leave_lazy_mmu_mode()
It seems fair to say that nested calls to
arch_{enter,leave}_lazy_mmu_mode() were not expected, and most
architectures never explicitly supported it.
Nesting does in fact occur in certain configurations, and avoiding it
has proved difficult. This series therefore enables lazy_mmu sections to
nest, on all architectures.
Nesting is handled using a counter in task_struct (patch 8), like other
stateless APIs such as pagefault_{disable,enable}(). This is fully
handled in a new generic layer in <linux/pgtable.h>; the arch_* API
remains unchanged. A new pair of calls, lazy_mmu_mode_{pause,resume}(),
is also introduced to allow functions that are called with the lazy MMU
mode enabled to temporarily pause it, regardless of nesting.
An arch now opts in to using the lazy MMU mode by selecting
CONFIG_ARCH_LAZY_MMU; this is more appropriate now that we have a
generic API, especially with state conditionally added to task_struct.
---
Background: Ryan Roberts' series from March [1] attempted to prevent
nesting from ever occurring, and mostly succeeded. Unfortunately, a
corner case (DEBUG_PAGEALLOC) may still cause nesting to occur on arm64.
Ryan proposed [2] to address that corner case at the generic level but
this approach received pushback; [3] then attempted to solve the issue
on arm64 only, but it was deemed too fragile.
It feels generally difficult to guarantee that lazy_mmu sections don't
nest, because callers of various standard mm functions do not know if
the function uses lazy_mmu itself.
The overall approach in v3/v4 is very close to what David Hildenbrand
proposed on v2 [4].
Unlike in v1/v2, no special provision is made for architectures to
save/restore extra state when entering/leaving the mode. Based on the
discussions so far, this does not seem to be required - an arch can
store any relevant state in thread_struct during arch_enter() and
restore it in arch_leave(). Nesting is not a concern as these functions
are only called at the top level, not in nested sections.
The introduction of a generic layer, and tracking of the lazy MMU state
in task_struct, also allows to streamline the arch callbacks - this
series removes 67 lines from arch/.
Patch overview:
* Patch 1: cleanup - avoids having to deal with the powerpc
context-switching code
* Patch 2-4: prepare arch_flush_lazy_mmu_mode() to be called from the
generic layer (patch 9)
* Patch 5: documentation clarification (not directly related to the
changes in this series)
* Patch 6-7: new API + CONFIG_ARCH_LAZY_MMU
* Patch 8: ensure correctness in interrupt context
* Patch 9: nesting support
* Patch 10-13: replace arch-specific tracking of lazy MMU mode with
generic API
* Patch 14: basic tests to ensure that the state added in patch 9 is
tracked correctly
This series has been tested by running the mm kselftests on arm64 with
DEBUG_VM, DEBUG_PAGEALLOC, KFENCE and KASAN. Extensive testing on
powerpc was also kindly provided by Venkat Rao Bagalkote [5]. It was
build-tested on other architectures (with and without XEN_PV on x86).
- Kevin
[1] https://lore.kernel.org/all/20250303141542.3371656-1-ryan.roberts@arm.com/
[2] https://lore.kernel.org/all/20250530140446.2387131-1-ryan.roberts@arm.com/
[3] https://lore.kernel.org/all/20250606135654.178300-1-ryan.roberts@arm.com/
[4] https://lore.kernel.org/all/ef343405-c394-4763-a79f-21381f217b6c@redhat.com/
[5] https://lore.kernel.org/all/94889730-1AEF-458F-B623-04092C0D6819@linux.ibm.com/
---
Changelog
v5..v6:
- Rebased on v6.19-rc1
- Overall: no functional change
- Patch 5: new patch clarifying that generic code may not sleep while in lazy
MMU mode [Alexander Gordeev]
- Patch 6: added description for the ARCH_HAS_LAZY_MMU_MODE option
[Anshuman Khandual]
- Patch 9: rename in_lazy_mmu_mode() to is_lazy_mmu_mode_active() [Alexander]
- Patch 14: new patch with basic KUnit tests [Anshuman]
- Collected R-b/A-b/T-b tags
v5: https://lore.kernel.org/all/20251124132228.622678-1-kevin.brodsky@arm.com/
v4..v5:
- Rebased on mm-unstable
- Patch 3: added missing radix_enabled() check in arch_flush()
[Ritesh Harjani]
- Patch 6: declare arch_flush_lazy_mmu_mode() as static inline on x86
[Ryan Roberts]
- Patch 7 (formerly 12): moved before patch 8 to ensure correctness in
interrupt context [Ryan]. The diffs in in_lazy_mmu_mode() and
queue_pte_barriers() are moved to patch 8 and 9 resp.
- Patch 8:
* Removed all restrictions regarding lazy_mmu_mode_{pause,resume}().
They may now be called even when lazy MMU isn't enabled, and
any call to lazy_mmu_mode_* may be made while paused (such calls
will be ignored). [David, Ryan]
* lazy_mmu_state.{nesting_level,active} are replaced with
{enable_count,pause_count} to track arbitrary nesting of both
enable/disable and pause/resume [Ryan]
* Added __task_lazy_mmu_mode_active() for use in patch 12 [David]
* Added documentation for all the functions [Ryan]
- Patch 9: keep existing test + set TIF_LAZY_MMU_PENDING instead of
atomic RMW [David, Ryan]
- Patch 12: use __task_lazy_mmu_mode_active() instead of accessing
lazy_mmu_state directly [David]
- Collected R-b/A-b tags
v4: https://lore.kernel.org/all/20251029100909.3381140-1-kevin.brodsky@arm.com/
v3..v4:
- Patch 2: restored ordering of preempt_{disable,enable}() [Dave Hansen]
- Patch 5 onwards: s/ARCH_LAZY_MMU/ARCH_HAS_LAZY_MMU_MODE/ [Mike Rapoport]
- Patch 7: renamed lazy_mmu_state members, removed VM_BUG_ON(),
reordered writes to lazy_mmu_state members [David Hildenbrand]
- Dropped patch 13 as it doesn't seem justified [David H]
- Various improvements to commit messages [David H]
v3: https://lore.kernel.org/all/20251015082727.2395128-1-kevin.brodsky@arm.com/
v2..v3:
- Full rewrite; dropped all Acked-by/Reviewed-by.
- Rebased on v6.18-rc1.
v2: https://lore.kernel.org/all/20250908073931.4159362-1-kevin.brodsky@arm.com/
v1..v2:
- Rebased on mm-unstable.
- Patch 2: handled new calls to enter()/leave(), clarified how the "flush"
pattern (leave() followed by enter()) is handled.
- Patch 5,6: removed unnecessary local variable [Alexander Gordeev's
suggestion].
- Added Mike Rapoport's Acked-by.
v1: https://lore.kernel.org/all/20250904125736.3918646-1-kevin.brodsky@arm.com/
---
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Andreas Larsson <andreas@gaisler.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jann Horn <jannh@google.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: "Liam R. Howlett" <Liam.Howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Will Deacon <will@kernel.org>
Cc: Yeoreum Yun <yeoreum.yun@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: sparclinux@vger.kernel.org
Cc: xen-devel@lists.xenproject.org
Cc: x86@kernel.org
---
Alexander Gordeev (1):
powerpc/64s: Do not re-activate batched TLB flush
Kevin Brodsky (13):
x86/xen: simplify flush_lazy_mmu()
powerpc/mm: implement arch_flush_lazy_mmu_mode()
sparc/mm: implement arch_flush_lazy_mmu_mode()
mm: clarify lazy_mmu sleeping constraints
mm: introduce CONFIG_ARCH_HAS_LAZY_MMU_MODE
mm: introduce generic lazy_mmu helpers
mm: bail out of lazy_mmu_mode_* in interrupt context
mm: enable lazy_mmu sections to nest
arm64: mm: replace TIF_LAZY_MMU with is_lazy_mmu_mode_active()
powerpc/mm: replace batch->active with is_lazy_mmu_mode_active()
sparc/mm: replace batch->active with is_lazy_mmu_mode_active()
x86/xen: use lazy_mmu_state when context-switching
mm: Add basic tests for lazy_mmu
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/pgtable.h | 41 +----
arch/arm64/include/asm/thread_info.h | 3 +-
arch/arm64/mm/mmu.c | 8 +-
arch/arm64/mm/pageattr.c | 4 +-
.../include/asm/book3s/64/tlbflush-hash.h | 20 +--
arch/powerpc/include/asm/thread_info.h | 2 -
arch/powerpc/kernel/process.c | 25 ---
arch/powerpc/mm/book3s64/hash_tlb.c | 10 +-
arch/powerpc/mm/book3s64/subpage_prot.c | 4 +-
arch/powerpc/platforms/Kconfig.cputype | 1 +
arch/sparc/Kconfig | 1 +
arch/sparc/include/asm/tlbflush_64.h | 5 +-
arch/sparc/mm/tlb.c | 14 +-
arch/x86/Kconfig | 1 +
arch/x86/boot/compressed/misc.h | 1 +
arch/x86/boot/startup/sme.c | 1 +
arch/x86/include/asm/paravirt.h | 1 -
arch/x86/include/asm/pgtable.h | 1 +
arch/x86/include/asm/thread_info.h | 4 +-
arch/x86/xen/enlighten_pv.c | 3 +-
arch/x86/xen/mmu_pv.c | 6 +-
fs/proc/task_mmu.c | 4 +-
include/linux/mm_types_task.h | 5 +
include/linux/pgtable.h | 158 +++++++++++++++++-
include/linux/sched.h | 45 +++++
mm/Kconfig | 19 +++
mm/Makefile | 1 +
mm/kasan/shadow.c | 8 +-
mm/madvise.c | 18 +-
mm/memory.c | 16 +-
mm/migrate_device.c | 8 +-
mm/mprotect.c | 4 +-
mm/mremap.c | 4 +-
mm/tests/lazy_mmu_mode_kunit.c | 71 ++++++++
mm/userfaultfd.c | 4 +-
mm/vmalloc.c | 12 +-
mm/vmscan.c | 12 +-
38 files changed, 380 insertions(+), 166 deletions(-)
create mode 100644 mm/tests/lazy_mmu_mode_kunit.c
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
--
2.51.2
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH v6 01/14] powerpc/64s: Do not re-activate batched TLB flush
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 02/14] x86/xen: simplify flush_lazy_mmu() Kevin Brodsky
` (13 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
From: Alexander Gordeev <agordeev@linux.ibm.com>
Since commit b9ef323ea168 ("powerpc/64s: Disable preemption in hash
lazy mmu mode") a task can not be preempted while in lazy MMU mode.
Therefore, the batch re-activation code is never called, so remove it.
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/powerpc/include/asm/thread_info.h | 2 --
arch/powerpc/kernel/process.c | 25 -------------------------
2 files changed, 27 deletions(-)
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index b0f200aba2b3..97f35f9b1a96 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -154,12 +154,10 @@ void arch_setup_new_exec(void);
/* Don't move TLF_NAPPING without adjusting the code in entry_32.S */
#define TLF_NAPPING 0 /* idle thread enabled NAP mode */
#define TLF_SLEEPING 1 /* suspend code enabled SLEEP mode */
-#define TLF_LAZY_MMU 3 /* tlb_batch is active */
#define TLF_RUNLATCH 4 /* Is the runlatch enabled? */
#define _TLF_NAPPING (1 << TLF_NAPPING)
#define _TLF_SLEEPING (1 << TLF_SLEEPING)
-#define _TLF_LAZY_MMU (1 << TLF_LAZY_MMU)
#define _TLF_RUNLATCH (1 << TLF_RUNLATCH)
#ifndef __ASSEMBLER__
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index a45fe147868b..a15d0b619b1f 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1281,9 +1281,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
{
struct thread_struct *new_thread, *old_thread;
struct task_struct *last;
-#ifdef CONFIG_PPC_64S_HASH_MMU
- struct ppc64_tlb_batch *batch;
-#endif
new_thread = &new->thread;
old_thread = ¤t->thread;
@@ -1291,14 +1288,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
WARN_ON(!irqs_disabled());
#ifdef CONFIG_PPC_64S_HASH_MMU
- batch = this_cpu_ptr(&ppc64_tlb_batch);
- if (batch->active) {
- current_thread_info()->local_flags |= _TLF_LAZY_MMU;
- if (batch->index)
- __flush_tlb_pending(batch);
- batch->active = 0;
- }
-
/*
* On POWER9 the copy-paste buffer can only paste into
* foreign real addresses, so unprivileged processes can not
@@ -1369,20 +1358,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
*/
#ifdef CONFIG_PPC_BOOK3S_64
-#ifdef CONFIG_PPC_64S_HASH_MMU
- /*
- * This applies to a process that was context switched while inside
- * arch_enter_lazy_mmu_mode(), to re-activate the batch that was
- * deactivated above, before _switch(). This will never be the case
- * for new tasks.
- */
- if (current_thread_info()->local_flags & _TLF_LAZY_MMU) {
- current_thread_info()->local_flags &= ~_TLF_LAZY_MMU;
- batch = this_cpu_ptr(&ppc64_tlb_batch);
- batch->active = 1;
- }
-#endif
-
/*
* Math facilities are masked out of the child MSR in copy_thread.
* A new task does not need to restore_math because it will
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 02/14] x86/xen: simplify flush_lazy_mmu()
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 01/14] powerpc/64s: Do not re-activate batched TLB flush Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 03/14] powerpc/mm: implement arch_flush_lazy_mmu_mode() Kevin Brodsky
` (12 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
arch_flush_lazy_mmu_mode() is called when outstanding batched
pgtable operations must be completed immediately. There should
however be no need to leave and re-enter lazy MMU completely. The
only part of that sequence that we really need is xen_mc_flush();
call it directly.
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/x86/xen/mmu_pv.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index 2a4a8deaf612..7a35c3393df4 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -2139,10 +2139,8 @@ static void xen_flush_lazy_mmu(void)
{
preempt_disable();
- if (xen_get_lazy_mode() == XEN_LAZY_MMU) {
- arch_leave_lazy_mmu_mode();
- arch_enter_lazy_mmu_mode();
- }
+ if (xen_get_lazy_mode() == XEN_LAZY_MMU)
+ xen_mc_flush();
preempt_enable();
}
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 03/14] powerpc/mm: implement arch_flush_lazy_mmu_mode()
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 01/14] powerpc/64s: Do not re-activate batched TLB flush Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 02/14] x86/xen: simplify flush_lazy_mmu() Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-16 5:14 ` Ritesh Harjani
2025-12-15 15:03 ` [PATCH v6 04/14] sparc/mm: " Kevin Brodsky
` (11 subsequent siblings)
14 siblings, 1 reply; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
Upcoming changes to the lazy_mmu API will cause
arch_flush_lazy_mmu_mode() to be called when leaving a nested
lazy_mmu section.
Move the relevant logic from arch_leave_lazy_mmu_mode() to
arch_flush_lazy_mmu_mode() and have the former call the latter. The
radix_enabled() check is required in both as
arch_flush_lazy_mmu_mode() will be called directly from the generic
layer in a subsequent patch.
Note: the additional this_cpu_ptr() and radix_enabled() calls on the
arch_leave_lazy_mmu_mode() path will be removed in a subsequent
patch.
Acked-by: David Hildenbrand <david@redhat.com>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
.../powerpc/include/asm/book3s/64/tlbflush-hash.h | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
index 146287d9580f..2d45f57df169 100644
--- a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
+++ b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
@@ -41,7 +41,7 @@ static inline void arch_enter_lazy_mmu_mode(void)
batch->active = 1;
}
-static inline void arch_leave_lazy_mmu_mode(void)
+static inline void arch_flush_lazy_mmu_mode(void)
{
struct ppc64_tlb_batch *batch;
@@ -51,12 +51,21 @@ static inline void arch_leave_lazy_mmu_mode(void)
if (batch->index)
__flush_tlb_pending(batch);
+}
+
+static inline void arch_leave_lazy_mmu_mode(void)
+{
+ struct ppc64_tlb_batch *batch;
+
+ if (radix_enabled())
+ return;
+ batch = this_cpu_ptr(&ppc64_tlb_batch);
+
+ arch_flush_lazy_mmu_mode();
batch->active = 0;
preempt_enable();
}
-#define arch_flush_lazy_mmu_mode() do {} while (0)
-
extern void hash__tlbiel_all(unsigned int action);
extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize,
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 04/14] sparc/mm: implement arch_flush_lazy_mmu_mode()
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (2 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 03/14] powerpc/mm: implement arch_flush_lazy_mmu_mode() Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 05/14] mm: clarify lazy_mmu sleeping constraints Kevin Brodsky
` (10 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
Upcoming changes to the lazy_mmu API will cause
arch_flush_lazy_mmu_mode() to be called when leaving a nested
lazy_mmu section.
Move the relevant logic from arch_leave_lazy_mmu_mode() to
arch_flush_lazy_mmu_mode() and have the former call the latter.
Note: the additional this_cpu_ptr() call on the
arch_leave_lazy_mmu_mode() path will be removed in a subsequent
patch.
Acked-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/sparc/include/asm/tlbflush_64.h | 2 +-
arch/sparc/mm/tlb.c | 9 ++++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h
index 8b8cdaa69272..925bb5d7a4e1 100644
--- a/arch/sparc/include/asm/tlbflush_64.h
+++ b/arch/sparc/include/asm/tlbflush_64.h
@@ -43,8 +43,8 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end);
void flush_tlb_pending(void);
void arch_enter_lazy_mmu_mode(void);
+void arch_flush_lazy_mmu_mode(void);
void arch_leave_lazy_mmu_mode(void);
-#define arch_flush_lazy_mmu_mode() do {} while (0)
/* Local cpu only. */
void __flush_tlb_all(void);
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index a35ddcca5e76..7b5dfcdb1243 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -59,12 +59,19 @@ void arch_enter_lazy_mmu_mode(void)
tb->active = 1;
}
-void arch_leave_lazy_mmu_mode(void)
+void arch_flush_lazy_mmu_mode(void)
{
struct tlb_batch *tb = this_cpu_ptr(&tlb_batch);
if (tb->tlb_nr)
flush_tlb_pending();
+}
+
+void arch_leave_lazy_mmu_mode(void)
+{
+ struct tlb_batch *tb = this_cpu_ptr(&tlb_batch);
+
+ arch_flush_lazy_mmu_mode();
tb->active = 0;
preempt_enable();
}
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 05/14] mm: clarify lazy_mmu sleeping constraints
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (3 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 04/14] sparc/mm: " Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 06/14] mm: introduce CONFIG_ARCH_HAS_LAZY_MMU_MODE Kevin Brodsky
` (9 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
The lazy MMU mode documentation makes clear that an implementation
should not assume that preemption is disabled or any lock is held
upon entry to the mode; however it says nothing about what code
using the lazy MMU interface should expect.
In practice sleeping is forbidden (for generic code) while the lazy
MMU mode is active: say it explicitly.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/pgtable.h | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 652f287c1ef6..1abc4a1c3d72 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -225,11 +225,15 @@ static inline int pmd_dirty(pmd_t pmd)
* up to date.
*
* In the general case, no lock is guaranteed to be held between entry and exit
- * of the lazy mode. So the implementation must assume preemption may be enabled
- * and cpu migration is possible; it must take steps to be robust against this.
- * (In practice, for user PTE updates, the appropriate page table lock(s) are
- * held, but for kernel PTE updates, no lock is held). Nesting is not permitted
- * and the mode cannot be used in interrupt context.
+ * of the lazy mode. (In practice, for user PTE updates, the appropriate page
+ * table lock(s) are held, but for kernel PTE updates, no lock is held).
+ * The implementation must therefore assume preemption may be enabled upon
+ * entry to the mode and cpu migration is possible; it must take steps to be
+ * robust against this. An implementation may handle this by disabling
+ * preemption, as a consequence generic code may not sleep while the lazy MMU
+ * mode is active.
+ *
+ * Nesting is not permitted and the mode cannot be used in interrupt context.
*/
#ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE
static inline void arch_enter_lazy_mmu_mode(void) {}
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 06/14] mm: introduce CONFIG_ARCH_HAS_LAZY_MMU_MODE
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (4 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 05/14] mm: clarify lazy_mmu sleeping constraints Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 07/14] mm: introduce generic lazy_mmu helpers Kevin Brodsky
` (8 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
Architectures currently opt in for implementing lazy_mmu helpers by
defining __HAVE_ARCH_ENTER_LAZY_MMU_MODE.
In preparation for introducing a generic lazy_mmu layer that will
require storage in task_struct, let's switch to a cleaner approach:
instead of defining a macro, select a CONFIG option.
This patch introduces CONFIG_ARCH_HAS_LAZY_MMU_MODE and has each
arch select it when it implements lazy_mmu helpers.
__HAVE_ARCH_ENTER_LAZY_MMU_MODE is removed and <linux/pgtable.h>
relies on the new CONFIG instead.
On x86, lazy_mmu helpers are only implemented if PARAVIRT_XXL is
selected. This creates some complications in arch/x86/boot/, because
a few files manually undefine PARAVIRT* options. As a result
<asm/paravirt.h> does not define the lazy_mmu helpers, but this
breaks the build as <linux/pgtable.h> only defines them if
!CONFIG_ARCH_HAS_LAZY_MMU_MODE. There does not seem to be a clean
way out of this - let's just undefine that new CONFIG too.
Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/pgtable.h | 1 -
arch/powerpc/include/asm/book3s/64/tlbflush-hash.h | 2 --
arch/powerpc/platforms/Kconfig.cputype | 1 +
arch/sparc/Kconfig | 1 +
arch/sparc/include/asm/tlbflush_64.h | 2 --
arch/x86/Kconfig | 1 +
arch/x86/boot/compressed/misc.h | 1 +
arch/x86/boot/startup/sme.c | 1 +
arch/x86/include/asm/paravirt.h | 1 -
include/linux/pgtable.h | 2 +-
mm/Kconfig | 7 +++++++
12 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 93173f0a09c7..3fb4603c0e16 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -35,6 +35,7 @@ config ARM64
select ARCH_HAS_KCOV
select ARCH_HAS_KERNEL_FPU_SUPPORT if KERNEL_MODE_NEON
select ARCH_HAS_KEEPINITRD
+ select ARCH_HAS_LAZY_MMU_MODE
select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_MEM_ENCRYPT
select ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 64d5f1d9cce9..f7d66c261347 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -80,7 +80,6 @@ static inline void queue_pte_barriers(void)
}
}
-#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
static inline void arch_enter_lazy_mmu_mode(void)
{
/*
diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
index 2d45f57df169..565c1b7c3eae 100644
--- a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
+++ b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
@@ -24,8 +24,6 @@ DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
-#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
-
static inline void arch_enter_lazy_mmu_mode(void)
{
struct ppc64_tlb_batch *batch;
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 4c321a8ea896..f399917c17bd 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -93,6 +93,7 @@ config PPC_BOOK3S_64
select IRQ_WORK
select PPC_64S_HASH_MMU if !PPC_RADIX_MMU
select KASAN_VMALLOC if KASAN
+ select ARCH_HAS_LAZY_MMU_MODE
config PPC_BOOK3E_64
bool "Embedded processors"
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index a630d373e645..2bad14744ca4 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -112,6 +112,7 @@ config SPARC64
select NEED_PER_CPU_PAGE_FIRST_CHUNK
select ARCH_SUPPORTS_SCHED_SMT if SMP
select ARCH_SUPPORTS_SCHED_MC if SMP
+ select ARCH_HAS_LAZY_MMU_MODE
config ARCH_PROC_KCORE_TEXT
def_bool y
diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h
index 925bb5d7a4e1..4e1036728e2f 100644
--- a/arch/sparc/include/asm/tlbflush_64.h
+++ b/arch/sparc/include/asm/tlbflush_64.h
@@ -39,8 +39,6 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
void flush_tlb_kernel_range(unsigned long start, unsigned long end);
-#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
-
void flush_tlb_pending(void);
void arch_enter_lazy_mmu_mode(void);
void arch_flush_lazy_mmu_mode(void);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 80527299f859..2427a66cb0fe 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -808,6 +808,7 @@ config PARAVIRT
config PARAVIRT_XXL
bool
depends on X86_64
+ select ARCH_HAS_LAZY_MMU_MODE
config PARAVIRT_DEBUG
bool "paravirt-ops debugging"
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index fd855e32c9b9..4f86c5903e03 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -11,6 +11,7 @@
#undef CONFIG_PARAVIRT
#undef CONFIG_PARAVIRT_XXL
#undef CONFIG_PARAVIRT_SPINLOCKS
+#undef CONFIG_ARCH_HAS_LAZY_MMU_MODE
#undef CONFIG_KASAN
#undef CONFIG_KASAN_GENERIC
diff --git a/arch/x86/boot/startup/sme.c b/arch/x86/boot/startup/sme.c
index e7ea65f3f1d6..b76a7c95dfe1 100644
--- a/arch/x86/boot/startup/sme.c
+++ b/arch/x86/boot/startup/sme.c
@@ -24,6 +24,7 @@
#undef CONFIG_PARAVIRT
#undef CONFIG_PARAVIRT_XXL
#undef CONFIG_PARAVIRT_SPINLOCKS
+#undef CONFIG_ARCH_HAS_LAZY_MMU_MODE
/*
* This code runs before CPU feature bits are set. By default, the
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index b5e59a7ba0d0..13f9cd31c8f8 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -526,7 +526,6 @@ static inline void arch_end_context_switch(struct task_struct *next)
PVOP_VCALL1(cpu.end_context_switch, next);
}
-#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
static inline void arch_enter_lazy_mmu_mode(void)
{
PVOP_VCALL0(mmu.lazy_mode.enter);
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 1abc4a1c3d72..d46d86959bd6 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -235,7 +235,7 @@ static inline int pmd_dirty(pmd_t pmd)
*
* Nesting is not permitted and the mode cannot be used in interrupt context.
*/
-#ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE
+#ifndef CONFIG_ARCH_HAS_LAZY_MMU_MODE
static inline void arch_enter_lazy_mmu_mode(void) {}
static inline void arch_leave_lazy_mmu_mode(void) {}
static inline void arch_flush_lazy_mmu_mode(void) {}
diff --git a/mm/Kconfig b/mm/Kconfig
index bd0ea5454af8..62073bd61544 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1464,6 +1464,13 @@ config PT_RECLAIM
config FIND_NORMAL_PAGE
def_bool n
+config ARCH_HAS_LAZY_MMU_MODE
+ bool
+ help
+ The architecture uses the lazy MMU mode. This allows changes to
+ MMU-related architectural state to be deferred until the mode is
+ exited. See <linux/pgtable.h> for details.
+
source "mm/damon/Kconfig"
endmenu
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 07/14] mm: introduce generic lazy_mmu helpers
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (5 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 06/14] mm: introduce CONFIG_ARCH_HAS_LAZY_MMU_MODE Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 08/14] mm: bail out of lazy_mmu_mode_* in interrupt context Kevin Brodsky
` (7 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
The implementation of the lazy MMU mode is currently entirely
arch-specific; core code directly calls arch helpers:
arch_{enter,leave}_lazy_mmu_mode().
We are about to introduce support for nested lazy MMU sections.
As things stand we'd have to duplicate that logic in every arch
implementing lazy_mmu - adding to a fair amount of logic
already duplicated across lazy_mmu implementations.
This patch therefore introduces a new generic layer that calls the
existing arch_* helpers. Two pair of calls are introduced:
* lazy_mmu_mode_enable() ... lazy_mmu_mode_disable()
This is the standard case where the mode is enabled for a given
block of code by surrounding it with enable() and disable()
calls.
* lazy_mmu_mode_pause() ... lazy_mmu_mode_resume()
This is for situations where the mode is temporarily disabled
by first calling pause() and then resume() (e.g. to prevent any
batching from occurring in a critical section).
The documentation in <linux/pgtable.h> will be updated in a
subsequent patch.
No functional change should be introduced at this stage.
The implementation of enable()/resume() and disable()/pause() is
currently identical, but nesting support will change that.
Most of the call sites have been updated using the following
Coccinelle script:
@@
@@
{
...
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
...
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
...
}
@@
@@
{
...
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_pause();
...
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_resume();
...
}
A couple of notes regarding x86:
* Xen is currently the only case where explicit handling is required
for lazy MMU when context-switching. This is purely an
implementation detail and using the generic lazy_mmu_mode_*
functions would cause trouble when nesting support is introduced,
because the generic functions must be called from the current task.
For that reason we still use arch_leave() and arch_enter() there.
* x86 calls arch_flush_lazy_mmu_mode() unconditionally in a few
places, but only defines it if PARAVIRT_XXL is selected, and we
are removing the fallback in <linux/pgtable.h>. Add a new fallback
definition to <asm/pgtable.h> to keep things building.
Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/mm/mmu.c | 8 +++----
arch/arm64/mm/pageattr.c | 4 ++--
arch/powerpc/mm/book3s64/hash_tlb.c | 8 +++----
arch/powerpc/mm/book3s64/subpage_prot.c | 4 ++--
arch/x86/include/asm/pgtable.h | 1 +
fs/proc/task_mmu.c | 4 ++--
include/linux/pgtable.h | 29 +++++++++++++++++++++----
mm/kasan/shadow.c | 8 +++----
mm/madvise.c | 18 +++++++--------
mm/memory.c | 16 +++++++-------
mm/migrate_device.c | 8 +++----
mm/mprotect.c | 4 ++--
mm/mremap.c | 4 ++--
mm/userfaultfd.c | 4 ++--
mm/vmalloc.c | 12 +++++-----
mm/vmscan.c | 12 +++++-----
16 files changed, 83 insertions(+), 61 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 9ae7ce00a7ef..76d359f02982 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -801,7 +801,7 @@ int split_kernel_leaf_mapping(unsigned long start, unsigned long end)
return -EINVAL;
mutex_lock(&pgtable_split_lock);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
/*
* The split_kernel_leaf_mapping_locked() may sleep, it is not a
@@ -823,7 +823,7 @@ int split_kernel_leaf_mapping(unsigned long start, unsigned long end)
ret = split_kernel_leaf_mapping_locked(end);
}
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
mutex_unlock(&pgtable_split_lock);
return ret;
}
@@ -884,10 +884,10 @@ static int range_split_to_ptes(unsigned long start, unsigned long end, gfp_t gfp
{
int ret;
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
ret = walk_kernel_page_table_range_lockless(start, end,
&split_to_ptes_ops, NULL, &gfp);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
return ret;
}
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index f0e784b963e6..508986608b49 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -110,7 +110,7 @@ static int update_range_prot(unsigned long start, unsigned long size,
if (WARN_ON_ONCE(ret))
return ret;
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
/*
* The caller must ensure that the range we are operating on does not
@@ -119,7 +119,7 @@ static int update_range_prot(unsigned long start, unsigned long size,
*/
ret = walk_kernel_page_table_range_lockless(start, start + size,
&pageattr_ops, NULL, &data);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
return ret;
}
diff --git a/arch/powerpc/mm/book3s64/hash_tlb.c b/arch/powerpc/mm/book3s64/hash_tlb.c
index 21fcad97ae80..787f7a0e27f0 100644
--- a/arch/powerpc/mm/book3s64/hash_tlb.c
+++ b/arch/powerpc/mm/book3s64/hash_tlb.c
@@ -205,7 +205,7 @@ void __flush_hash_table_range(unsigned long start, unsigned long end)
* way to do things but is fine for our needs here.
*/
local_irq_save(flags);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
for (; start < end; start += PAGE_SIZE) {
pte_t *ptep = find_init_mm_pte(start, &hugepage_shift);
unsigned long pte;
@@ -217,7 +217,7 @@ void __flush_hash_table_range(unsigned long start, unsigned long end)
continue;
hpte_need_flush(&init_mm, start, ptep, pte, hugepage_shift);
}
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
local_irq_restore(flags);
}
@@ -237,7 +237,7 @@ void flush_hash_table_pmd_range(struct mm_struct *mm, pmd_t *pmd, unsigned long
* way to do things but is fine for our needs here.
*/
local_irq_save(flags);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
start_pte = pte_offset_map(pmd, addr);
if (!start_pte)
goto out;
@@ -249,6 +249,6 @@ void flush_hash_table_pmd_range(struct mm_struct *mm, pmd_t *pmd, unsigned long
}
pte_unmap(start_pte);
out:
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
local_irq_restore(flags);
}
diff --git a/arch/powerpc/mm/book3s64/subpage_prot.c b/arch/powerpc/mm/book3s64/subpage_prot.c
index ec98e526167e..07c47673bba2 100644
--- a/arch/powerpc/mm/book3s64/subpage_prot.c
+++ b/arch/powerpc/mm/book3s64/subpage_prot.c
@@ -73,13 +73,13 @@ static void hpte_flush_range(struct mm_struct *mm, unsigned long addr,
pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return;
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
for (; npages > 0; --npages) {
pte_update(mm, addr, pte, 0, 0, 0);
addr += PAGE_SIZE;
++pte;
}
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(pte - 1, ptl);
}
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index e33df3da6980..2842fa1f7a2c 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -118,6 +118,7 @@ extern pmdval_t early_pmd_flags;
#define __pte(x) native_make_pte(x)
#define arch_end_context_switch(prev) do {} while(0)
+static inline void arch_flush_lazy_mmu_mode(void) {}
#endif /* CONFIG_PARAVIRT_XXL */
static inline pmd_t pmd_set_flags(pmd_t pmd, pmdval_t set)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 81dfc26bfae8..480db575553e 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -2739,7 +2739,7 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
return 0;
}
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
if ((p->arg.flags & PM_SCAN_WP_MATCHING) && !p->vec_out) {
/* Fast path for performing exclusive WP */
@@ -2809,7 +2809,7 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
if (flush_end)
flush_tlb_range(vma, start, addr);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(start_pte, ptl);
cond_resched();
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index d46d86959bd6..116a18b7916c 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -235,10 +235,31 @@ static inline int pmd_dirty(pmd_t pmd)
*
* Nesting is not permitted and the mode cannot be used in interrupt context.
*/
-#ifndef CONFIG_ARCH_HAS_LAZY_MMU_MODE
-static inline void arch_enter_lazy_mmu_mode(void) {}
-static inline void arch_leave_lazy_mmu_mode(void) {}
-static inline void arch_flush_lazy_mmu_mode(void) {}
+#ifdef CONFIG_ARCH_HAS_LAZY_MMU_MODE
+static inline void lazy_mmu_mode_enable(void)
+{
+ arch_enter_lazy_mmu_mode();
+}
+
+static inline void lazy_mmu_mode_disable(void)
+{
+ arch_leave_lazy_mmu_mode();
+}
+
+static inline void lazy_mmu_mode_pause(void)
+{
+ arch_leave_lazy_mmu_mode();
+}
+
+static inline void lazy_mmu_mode_resume(void)
+{
+ arch_enter_lazy_mmu_mode();
+}
+#else
+static inline void lazy_mmu_mode_enable(void) {}
+static inline void lazy_mmu_mode_disable(void) {}
+static inline void lazy_mmu_mode_pause(void) {}
+static inline void lazy_mmu_mode_resume(void) {}
#endif
#ifndef pte_batch_hint
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index 29a751a8a08d..c1433d5cc5db 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -305,7 +305,7 @@ static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
pte_t pte;
int index;
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_pause();
index = PFN_DOWN(addr - data->start);
page = data->pages[index];
@@ -319,7 +319,7 @@ static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
}
spin_unlock(&init_mm.page_table_lock);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_resume();
return 0;
}
@@ -471,7 +471,7 @@ static int kasan_depopulate_vmalloc_pte(pte_t *ptep, unsigned long addr,
pte_t pte;
int none;
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_pause();
spin_lock(&init_mm.page_table_lock);
pte = ptep_get(ptep);
@@ -483,7 +483,7 @@ static int kasan_depopulate_vmalloc_pte(pte_t *ptep, unsigned long addr,
if (likely(!none))
__free_page(pfn_to_page(pte_pfn(pte)));
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_resume();
return 0;
}
diff --git a/mm/madvise.c b/mm/madvise.c
index b617b1be0f53..6bf7009fa5ce 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -453,7 +453,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
if (!start_pte)
return 0;
flush_tlb_batched_pending(mm);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
for (; addr < end; pte += nr, addr += nr * PAGE_SIZE) {
nr = 1;
ptent = ptep_get(pte);
@@ -461,7 +461,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
if (++batch_count == SWAP_CLUSTER_MAX) {
batch_count = 0;
if (need_resched()) {
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(start_pte, ptl);
cond_resched();
goto restart;
@@ -497,7 +497,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
if (!folio_trylock(folio))
continue;
folio_get(folio);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(start_pte, ptl);
start_pte = NULL;
err = split_folio(folio);
@@ -508,7 +508,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
if (!start_pte)
break;
flush_tlb_batched_pending(mm);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
if (!err)
nr = 0;
continue;
@@ -556,7 +556,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
}
if (start_pte) {
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(start_pte, ptl);
}
if (pageout)
@@ -675,7 +675,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
if (!start_pte)
return 0;
flush_tlb_batched_pending(mm);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
for (; addr != end; pte += nr, addr += PAGE_SIZE * nr) {
nr = 1;
ptent = ptep_get(pte);
@@ -724,7 +724,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
if (!folio_trylock(folio))
continue;
folio_get(folio);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(start_pte, ptl);
start_pte = NULL;
err = split_folio(folio);
@@ -735,7 +735,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
if (!start_pte)
break;
flush_tlb_batched_pending(mm);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
if (!err)
nr = 0;
continue;
@@ -775,7 +775,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
if (nr_swap)
add_mm_counter(mm, MM_SWAPENTS, nr_swap);
if (start_pte) {
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(start_pte, ptl);
}
cond_resched();
diff --git a/mm/memory.c b/mm/memory.c
index 2a55edc48a65..ee15303c4041 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1256,7 +1256,7 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
orig_src_pte = src_pte;
orig_dst_pte = dst_pte;
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
do {
nr = 1;
@@ -1325,7 +1325,7 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
} while (dst_pte += nr, src_pte += nr, addr += PAGE_SIZE * nr,
addr != end);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(orig_src_pte, src_ptl);
add_mm_rss_vec(dst_mm, rss);
pte_unmap_unlock(orig_dst_pte, dst_ptl);
@@ -1842,7 +1842,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
return addr;
flush_tlb_batched_pending(mm);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
do {
bool any_skipped = false;
@@ -1874,7 +1874,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
direct_reclaim = try_get_and_clear_pmd(mm, pmd, &pmdval);
add_mm_rss_vec(mm, rss);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
/* Do the actual TLB flush before dropping ptl */
if (force_flush) {
@@ -2813,7 +2813,7 @@ static int remap_pte_range(struct mm_struct *mm, pmd_t *pmd,
mapped_pte = pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
do {
BUG_ON(!pte_none(ptep_get(pte)));
if (!pfn_modify_allowed(pfn, prot)) {
@@ -2823,7 +2823,7 @@ static int remap_pte_range(struct mm_struct *mm, pmd_t *pmd,
set_pte_at(mm, addr, pte, pte_mkspecial(pfn_pte(pfn, prot)));
pfn++;
} while (pte++, addr += PAGE_SIZE, addr != end);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(mapped_pte, ptl);
return err;
}
@@ -3174,7 +3174,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
return -EINVAL;
}
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
if (fn) {
do {
@@ -3187,7 +3187,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
}
*mask |= PGTBL_PTE_MODIFIED;
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
if (mm != &init_mm)
pte_unmap_unlock(mapped_pte, ptl);
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 23379663b1e1..0346c2d7819f 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -271,7 +271,7 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
ptep = pte_offset_map_lock(mm, pmdp, start, &ptl);
if (!ptep)
goto again;
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
ptep += (addr - start) / PAGE_SIZE;
for (; addr < end; addr += PAGE_SIZE, ptep++) {
@@ -313,7 +313,7 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
if (folio_test_large(folio)) {
int ret;
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(ptep, ptl);
ret = migrate_vma_split_folio(folio,
migrate->fault_page);
@@ -356,7 +356,7 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
if (folio && folio_test_large(folio)) {
int ret;
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(ptep, ptl);
ret = migrate_vma_split_folio(folio,
migrate->fault_page);
@@ -485,7 +485,7 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
if (unmapped)
flush_tlb_range(walk->vma, start, end);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(ptep - 1, ptl);
return 0;
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 283889e4f1ce..c0571445bef7 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -233,7 +233,7 @@ static long change_pte_range(struct mmu_gather *tlb,
is_private_single_threaded = vma_is_single_threaded_private(vma);
flush_tlb_batched_pending(vma->vm_mm);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
do {
nr_ptes = 1;
oldpte = ptep_get(pte);
@@ -379,7 +379,7 @@ static long change_pte_range(struct mmu_gather *tlb,
}
}
} while (pte += nr_ptes, addr += nr_ptes * PAGE_SIZE, addr != end);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(pte - 1, ptl);
return pages;
diff --git a/mm/mremap.c b/mm/mremap.c
index 672264807db6..8275b9772ec1 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -260,7 +260,7 @@ static int move_ptes(struct pagetable_move_control *pmc,
if (new_ptl != old_ptl)
spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
flush_tlb_batched_pending(vma->vm_mm);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
for (; old_addr < old_end; old_ptep += nr_ptes, old_addr += nr_ptes * PAGE_SIZE,
new_ptep += nr_ptes, new_addr += nr_ptes * PAGE_SIZE) {
@@ -305,7 +305,7 @@ static int move_ptes(struct pagetable_move_control *pmc,
}
}
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
if (force_flush)
flush_tlb_range(vma, old_end - len, old_end);
if (new_ptl != old_ptl)
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index e6dfd5f28acd..b11f81095fa5 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -1103,7 +1103,7 @@ static long move_present_ptes(struct mm_struct *mm,
/* It's safe to drop the reference now as the page-table is holding one. */
folio_put(*first_src_folio);
*first_src_folio = NULL;
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
while (true) {
orig_src_pte = ptep_get_and_clear(mm, src_addr, src_pte);
@@ -1140,7 +1140,7 @@ static long move_present_ptes(struct mm_struct *mm,
break;
}
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
if (src_addr > src_start)
flush_tlb_range(src_vma, src_start, src_addr);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index ecbac900c35f..1dea299fbb5a 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -108,7 +108,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
if (!pte)
return -ENOMEM;
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
do {
if (unlikely(!pte_none(ptep_get(pte)))) {
@@ -134,7 +134,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
pfn++;
} while (pte += PFN_DOWN(size), addr += size, addr != end);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
*mask |= PGTBL_PTE_MODIFIED;
return 0;
}
@@ -366,7 +366,7 @@ static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
unsigned long size = PAGE_SIZE;
pte = pte_offset_kernel(pmd, addr);
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
do {
#ifdef CONFIG_HUGETLB_PAGE
@@ -385,7 +385,7 @@ static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
WARN_ON(!pte_none(ptent) && !pte_present(ptent));
} while (pte += (size >> PAGE_SHIFT), addr += size, addr != end);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
*mask |= PGTBL_PTE_MODIFIED;
}
@@ -533,7 +533,7 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
if (!pte)
return -ENOMEM;
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
do {
struct page *page = pages[*nr];
@@ -555,7 +555,7 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
(*nr)++;
} while (pte++, addr += PAGE_SIZE, addr != end);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
*mask |= PGTBL_PTE_MODIFIED;
return err;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 670fe9fae5ba..ab7ca55ca0f3 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3516,7 +3516,7 @@ static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end,
return false;
}
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
restart:
for (i = pte_index(start), addr = start; addr != end; i++, addr += PAGE_SIZE) {
unsigned long pfn;
@@ -3557,7 +3557,7 @@ static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end,
if (i < PTRS_PER_PTE && get_next_vma(PMD_MASK, PAGE_SIZE, args, &start, &end))
goto restart;
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
pte_unmap_unlock(pte, ptl);
return suitable_to_scan(total, young);
@@ -3598,7 +3598,7 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area
if (!spin_trylock(ptl))
goto done;
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
do {
unsigned long pfn;
@@ -3645,7 +3645,7 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area
walk_update_folio(walk, last, gen, dirty);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
spin_unlock(ptl);
done:
*first = -1;
@@ -4244,7 +4244,7 @@ bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
}
}
- arch_enter_lazy_mmu_mode();
+ lazy_mmu_mode_enable();
pte -= (addr - start) / PAGE_SIZE;
@@ -4278,7 +4278,7 @@ bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
walk_update_folio(walk, last, gen, dirty);
- arch_leave_lazy_mmu_mode();
+ lazy_mmu_mode_disable();
/* feedback from rmap walkers to page table walkers */
if (mm_state && suitable_to_scan(i, young))
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 08/14] mm: bail out of lazy_mmu_mode_* in interrupt context
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (6 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 07/14] mm: introduce generic lazy_mmu helpers Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 09/14] mm: enable lazy_mmu sections to nest Kevin Brodsky
` (6 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86,
David Hildenbrand (Red Hat)
The lazy MMU mode cannot be used in interrupt context. This is
documented in <linux/pgtable.h>, but isn't consistently handled
across architectures.
arm64 ensures that calls to lazy_mmu_mode_* have no effect in
interrupt context, because such calls do occur in certain
configurations - see commit b81c688426a9 ("arm64/mm: Disable barrier
batching in interrupt contexts"). Other architectures do not check
this situation, most likely because it hasn't occurred so far.
Let's handle this in the new generic lazy_mmu layer, in the same
fashion as arm64: bail out of lazy_mmu_mode_* if in_interrupt().
Also remove the arm64 handling that is now redundant.
Both arm64 and x86/Xen also ensure that any lazy MMU optimisation is
disabled while in interrupt (see queue_pte_barriers() and
xen_get_lazy_mode() respectively). This will be handled in the
generic layer in a subsequent patch.
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/include/asm/pgtable.h | 9 ---------
include/linux/pgtable.h | 17 ++++++++++++++++-
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index f7d66c261347..bf9178902bdb 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -94,26 +94,17 @@ static inline void arch_enter_lazy_mmu_mode(void)
* keeps tracking simple.
*/
- if (in_interrupt())
- return;
-
set_thread_flag(TIF_LAZY_MMU);
}
static inline void arch_flush_lazy_mmu_mode(void)
{
- if (in_interrupt())
- return;
-
if (test_and_clear_thread_flag(TIF_LAZY_MMU_PENDING))
emit_pte_barriers();
}
static inline void arch_leave_lazy_mmu_mode(void)
{
- if (in_interrupt())
- return;
-
arch_flush_lazy_mmu_mode();
clear_thread_flag(TIF_LAZY_MMU);
}
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 116a18b7916c..dddde6873d1e 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -233,26 +233,41 @@ static inline int pmd_dirty(pmd_t pmd)
* preemption, as a consequence generic code may not sleep while the lazy MMU
* mode is active.
*
- * Nesting is not permitted and the mode cannot be used in interrupt context.
+ * The mode is disabled in interrupt context and calls to the lazy_mmu API have
+ * no effect.
+ *
+ * Nesting is not permitted.
*/
#ifdef CONFIG_ARCH_HAS_LAZY_MMU_MODE
static inline void lazy_mmu_mode_enable(void)
{
+ if (in_interrupt())
+ return;
+
arch_enter_lazy_mmu_mode();
}
static inline void lazy_mmu_mode_disable(void)
{
+ if (in_interrupt())
+ return;
+
arch_leave_lazy_mmu_mode();
}
static inline void lazy_mmu_mode_pause(void)
{
+ if (in_interrupt())
+ return;
+
arch_leave_lazy_mmu_mode();
}
static inline void lazy_mmu_mode_resume(void)
{
+ if (in_interrupt())
+ return;
+
arch_enter_lazy_mmu_mode();
}
#else
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 09/14] mm: enable lazy_mmu sections to nest
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (7 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 08/14] mm: bail out of lazy_mmu_mode_* in interrupt context Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 10/14] arm64: mm: replace TIF_LAZY_MMU with is_lazy_mmu_mode_active() Kevin Brodsky
` (5 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86,
David Hildenbrand (Red Hat)
Despite recent efforts to prevent lazy_mmu sections from nesting, it
remains difficult to ensure that it never occurs - and in fact it
does occur on arm64 in certain situations (CONFIG_DEBUG_PAGEALLOC).
Commit 1ef3095b1405 ("arm64/mm: Permit lazy_mmu_mode to be nested")
made nesting tolerable on arm64, but without truly supporting it:
the inner call to leave() disables the batching optimisation before
the outer section ends.
This patch actually enables lazy_mmu sections to nest by tracking
the nesting level in task_struct, in a similar fashion to e.g.
pagefault_{enable,disable}(). This is fully handled by the generic
lazy_mmu helpers that were recently introduced.
lazy_mmu sections were not initially intended to nest, so we need to
clarify the semantics w.r.t. the arch_*_lazy_mmu_mode() callbacks.
This patch takes the following approach:
* The outermost calls to lazy_mmu_mode_{enable,disable}() trigger
calls to arch_{enter,leave}_lazy_mmu_mode() - this is unchanged.
* Nested calls to lazy_mmu_mode_{enable,disable}() are not forwarded
to the arch via arch_{enter,leave} - lazy MMU remains enabled so
the assumption is that these callbacks are not relevant. However,
existing code may rely on a call to disable() to flush any batched
state, regardless of nesting. arch_flush_lazy_mmu_mode() is
therefore called in that situation.
A separate interface was recently introduced to temporarily pause
the lazy MMU mode: lazy_mmu_mode_{pause,resume}(). pause() fully
exits the mode *regardless of the nesting level*, and resume()
restores the mode at the same nesting level.
pause()/resume() are themselves allowed to nest, so we actually
store two nesting levels in task_struct: enable_count and
pause_count. A new helper is_lazy_mmu_mode_active() is introduced to
determine whether we are currently in lazy MMU mode; this will be
used in subsequent patches to replace the various ways arch's
currently track whether the mode is enabled.
In summary (enable/pause represent the values *after* the call):
lazy_mmu_mode_enable() -> arch_enter() enable=1 pause=0
lazy_mmu_mode_enable() -> ø enable=2 pause=0
lazy_mmu_mode_pause() -> arch_leave() enable=2 pause=1
lazy_mmu_mode_resume() -> arch_enter() enable=2 pause=0
lazy_mmu_mode_disable() -> arch_flush() enable=1 pause=0
lazy_mmu_mode_disable() -> arch_leave() enable=0 pause=0
Note: is_lazy_mmu_mode_active() is added to <linux/sched.h> to allow
arch headers included by <linux/pgtable.h> to use it.
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/include/asm/pgtable.h | 12 ----
include/linux/mm_types_task.h | 5 ++
include/linux/pgtable.h | 114 +++++++++++++++++++++++++++++--
include/linux/sched.h | 45 ++++++++++++
4 files changed, 157 insertions(+), 19 deletions(-)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index bf9178902bdb..7f528c36d53c 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -82,18 +82,6 @@ static inline void queue_pte_barriers(void)
static inline void arch_enter_lazy_mmu_mode(void)
{
- /*
- * lazy_mmu_mode is not supposed to permit nesting. But in practice this
- * does happen with CONFIG_DEBUG_PAGEALLOC, where a page allocation
- * inside a lazy_mmu_mode section (such as zap_pte_range()) will change
- * permissions on the linear map with apply_to_page_range(), which
- * re-enters lazy_mmu_mode. So we tolerate nesting in our
- * implementation. The first call to arch_leave_lazy_mmu_mode() will
- * flush and clear the flag such that the remainder of the work in the
- * outer nest behaves as if outside of lazy mmu mode. This is safe and
- * keeps tracking simple.
- */
-
set_thread_flag(TIF_LAZY_MMU);
}
diff --git a/include/linux/mm_types_task.h b/include/linux/mm_types_task.h
index a82aa80c0ba4..11bf319d78ec 100644
--- a/include/linux/mm_types_task.h
+++ b/include/linux/mm_types_task.h
@@ -88,4 +88,9 @@ struct tlbflush_unmap_batch {
#endif
};
+struct lazy_mmu_state {
+ u8 enable_count;
+ u8 pause_count;
+};
+
#endif /* _LINUX_MM_TYPES_TASK_H */
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index dddde6873d1e..2f0dd3a4ace1 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -236,39 +236,139 @@ static inline int pmd_dirty(pmd_t pmd)
* The mode is disabled in interrupt context and calls to the lazy_mmu API have
* no effect.
*
- * Nesting is not permitted.
+ * The lazy MMU mode is enabled for a given block of code using:
+ *
+ * lazy_mmu_mode_enable();
+ * <code>
+ * lazy_mmu_mode_disable();
+ *
+ * Nesting is permitted: <code> may itself use an enable()/disable() pair.
+ * A nested call to enable() has no functional effect; however disable() causes
+ * any batched architectural state to be flushed regardless of nesting. After a
+ * call to disable(), the caller can therefore rely on all previous page table
+ * modifications to have taken effect, but the lazy MMU mode may still be
+ * enabled.
+ *
+ * In certain cases, it may be desirable to temporarily pause the lazy MMU mode.
+ * This can be done using:
+ *
+ * lazy_mmu_mode_pause();
+ * <code>
+ * lazy_mmu_mode_resume();
+ *
+ * pause() ensures that the mode is exited regardless of the nesting level;
+ * resume() re-enters the mode at the same nesting level. Any call to the
+ * lazy_mmu_mode_* API between those two calls has no effect. In particular,
+ * this means that pause()/resume() pairs may nest.
+ *
+ * is_lazy_mmu_mode_active() can be used to check whether the lazy MMU mode is
+ * currently enabled.
*/
#ifdef CONFIG_ARCH_HAS_LAZY_MMU_MODE
+/**
+ * lazy_mmu_mode_enable() - Enable the lazy MMU mode.
+ *
+ * Enters a new lazy MMU mode section; if the mode was not already enabled,
+ * enables it and calls arch_enter_lazy_mmu_mode().
+ *
+ * Must be paired with a call to lazy_mmu_mode_disable().
+ *
+ * Has no effect if called:
+ * - While paused - see lazy_mmu_mode_pause()
+ * - In interrupt context
+ */
static inline void lazy_mmu_mode_enable(void)
{
- if (in_interrupt())
+ struct lazy_mmu_state *state = ¤t->lazy_mmu_state;
+
+ if (in_interrupt() || state->pause_count > 0)
return;
- arch_enter_lazy_mmu_mode();
+ VM_WARN_ON_ONCE(state->enable_count == U8_MAX);
+
+ if (state->enable_count++ == 0)
+ arch_enter_lazy_mmu_mode();
}
+/**
+ * lazy_mmu_mode_disable() - Disable the lazy MMU mode.
+ *
+ * Exits the current lazy MMU mode section. If it is the outermost section,
+ * disables the mode and calls arch_leave_lazy_mmu_mode(). Otherwise (nested
+ * section), calls arch_flush_lazy_mmu_mode().
+ *
+ * Must match a call to lazy_mmu_mode_enable().
+ *
+ * Has no effect if called:
+ * - While paused - see lazy_mmu_mode_pause()
+ * - In interrupt context
+ */
static inline void lazy_mmu_mode_disable(void)
{
- if (in_interrupt())
+ struct lazy_mmu_state *state = ¤t->lazy_mmu_state;
+
+ if (in_interrupt() || state->pause_count > 0)
return;
- arch_leave_lazy_mmu_mode();
+ VM_WARN_ON_ONCE(state->enable_count == 0);
+
+ if (--state->enable_count == 0)
+ arch_leave_lazy_mmu_mode();
+ else /* Exiting a nested section */
+ arch_flush_lazy_mmu_mode();
+
}
+/**
+ * lazy_mmu_mode_pause() - Pause the lazy MMU mode.
+ *
+ * Pauses the lazy MMU mode; if it is currently active, disables it and calls
+ * arch_leave_lazy_mmu_mode().
+ *
+ * Must be paired with a call to lazy_mmu_mode_resume(). Calls to the
+ * lazy_mmu_mode_* API have no effect until the matching resume() call.
+ *
+ * Has no effect if called:
+ * - While paused (inside another pause()/resume() pair)
+ * - In interrupt context
+ */
static inline void lazy_mmu_mode_pause(void)
{
+ struct lazy_mmu_state *state = ¤t->lazy_mmu_state;
+
if (in_interrupt())
return;
- arch_leave_lazy_mmu_mode();
+ VM_WARN_ON_ONCE(state->pause_count == U8_MAX);
+
+ if (state->pause_count++ == 0 && state->enable_count > 0)
+ arch_leave_lazy_mmu_mode();
}
+/**
+ * lazy_mmu_mode_resume() - Resume the lazy MMU mode.
+ *
+ * Resumes the lazy MMU mode; if it was active at the point where the matching
+ * call to lazy_mmu_mode_pause() was made, re-enables it and calls
+ * arch_enter_lazy_mmu_mode().
+ *
+ * Must match a call to lazy_mmu_mode_pause().
+ *
+ * Has no effect if called:
+ * - While paused (inside another pause()/resume() pair)
+ * - In interrupt context
+ */
static inline void lazy_mmu_mode_resume(void)
{
+ struct lazy_mmu_state *state = ¤t->lazy_mmu_state;
+
if (in_interrupt())
return;
- arch_enter_lazy_mmu_mode();
+ VM_WARN_ON_ONCE(state->pause_count == 0);
+
+ if (--state->pause_count == 0 && state->enable_count > 0)
+ arch_enter_lazy_mmu_mode();
}
#else
static inline void lazy_mmu_mode_enable(void) {}
diff --git a/include/linux/sched.h b/include/linux/sched.h
index d395f2810fac..f2fc6584c790 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1419,6 +1419,10 @@ struct task_struct {
struct page_frag task_frag;
+#ifdef CONFIG_ARCH_HAS_LAZY_MMU_MODE
+ struct lazy_mmu_state lazy_mmu_state;
+#endif
+
#ifdef CONFIG_TASK_DELAY_ACCT
struct task_delay_info *delays;
#endif
@@ -1702,6 +1706,47 @@ static inline char task_state_to_char(struct task_struct *tsk)
return task_index_to_char(task_state_index(tsk));
}
+#ifdef CONFIG_ARCH_HAS_LAZY_MMU_MODE
+/**
+ * __task_lazy_mmu_mode_active() - Test the lazy MMU mode state for a task.
+ * @tsk: The task to check.
+ *
+ * Test whether @tsk has its lazy MMU mode state set to active (i.e. enabled
+ * and not paused).
+ *
+ * This function only considers the state saved in task_struct; to test whether
+ * current actually is in lazy MMU mode, is_lazy_mmu_mode_active() should be
+ * used instead.
+ *
+ * This function is intended for architectures that implement the lazy MMU
+ * mode; it must not be called from generic code.
+ */
+static inline bool __task_lazy_mmu_mode_active(struct task_struct *tsk)
+{
+ struct lazy_mmu_state *state = &tsk->lazy_mmu_state;
+
+ return state->enable_count > 0 && state->pause_count == 0;
+}
+
+/**
+ * is_lazy_mmu_mode_active() - Test whether we are currently in lazy MMU mode.
+ *
+ * Test whether the current context is in lazy MMU mode. This is true if both:
+ * 1. We are not in interrupt context
+ * 2. Lazy MMU mode is active for the current task
+ *
+ * This function is intended for architectures that implement the lazy MMU
+ * mode; it must not be called from generic code.
+ */
+static inline bool is_lazy_mmu_mode_active(void)
+{
+ if (in_interrupt())
+ return false;
+
+ return __task_lazy_mmu_mode_active(current);
+}
+#endif
+
extern struct pid *cad_pid;
/*
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 10/14] arm64: mm: replace TIF_LAZY_MMU with is_lazy_mmu_mode_active()
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (8 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 09/14] mm: enable lazy_mmu sections to nest Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 11/14] powerpc/mm: replace batch->active " Kevin Brodsky
` (4 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86,
David Hildenbrand (Red Hat)
The generic lazy_mmu layer now tracks whether a task is in lazy MMU
mode. As a result we no longer need a TIF flag for that purpose -
let's use the new is_lazy_mmu_mode_active() helper instead.
The explicit check for in_interrupt() is no longer necessary either
as is_lazy_mmu_mode_active() always returns false in interrupt
context.
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/include/asm/pgtable.h | 19 +++----------------
arch/arm64/include/asm/thread_info.h | 3 +--
2 files changed, 4 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7f528c36d53c..445e18e92221 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -62,28 +62,16 @@ static inline void emit_pte_barriers(void)
static inline void queue_pte_barriers(void)
{
- unsigned long flags;
-
- if (in_interrupt()) {
- emit_pte_barriers();
- return;
- }
-
- flags = read_thread_flags();
-
- if (flags & BIT(TIF_LAZY_MMU)) {
+ if (is_lazy_mmu_mode_active()) {
/* Avoid the atomic op if already set. */
- if (!(flags & BIT(TIF_LAZY_MMU_PENDING)))
+ if (!test_thread_flag(TIF_LAZY_MMU_PENDING))
set_thread_flag(TIF_LAZY_MMU_PENDING);
} else {
emit_pte_barriers();
}
}
-static inline void arch_enter_lazy_mmu_mode(void)
-{
- set_thread_flag(TIF_LAZY_MMU);
-}
+static inline void arch_enter_lazy_mmu_mode(void) {}
static inline void arch_flush_lazy_mmu_mode(void)
{
@@ -94,7 +82,6 @@ static inline void arch_flush_lazy_mmu_mode(void)
static inline void arch_leave_lazy_mmu_mode(void)
{
arch_flush_lazy_mmu_mode();
- clear_thread_flag(TIF_LAZY_MMU);
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index a803b887b0b4..e7cd017b07c8 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -84,8 +84,7 @@ void arch_setup_new_exec(void);
#define TIF_SME_VL_INHERIT 28 /* Inherit SME vl_onexec across exec */
#define TIF_KERNEL_FPSTATE 29 /* Task is in a kernel mode FPSIMD section */
#define TIF_TSC_SIGSEGV 30 /* SIGSEGV on counter-timer access */
-#define TIF_LAZY_MMU 31 /* Task in lazy mmu mode */
-#define TIF_LAZY_MMU_PENDING 32 /* Ops pending for lazy mmu mode exit */
+#define TIF_LAZY_MMU_PENDING 31 /* Ops pending for lazy mmu mode exit */
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 11/14] powerpc/mm: replace batch->active with is_lazy_mmu_mode_active()
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (9 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 10/14] arm64: mm: replace TIF_LAZY_MMU with is_lazy_mmu_mode_active() Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 12/14] sparc/mm: " Kevin Brodsky
` (3 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
A per-CPU batch struct is activated when entering lazy MMU mode; its
lifetime is the same as the lazy MMU section (it is deactivated when
leaving the mode). Preemption is disabled in that interval to ensure
that the per-CPU reference remains valid.
The generic lazy_mmu layer now tracks whether a task is in lazy MMU
mode. We can therefore use the generic helper
is_lazy_mmu_mode_active() to tell whether a batch struct is active
instead of tracking it explicitly.
Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/powerpc/include/asm/book3s/64/tlbflush-hash.h | 9 ---------
arch/powerpc/mm/book3s64/hash_tlb.c | 2 +-
2 files changed, 1 insertion(+), 10 deletions(-)
diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
index 565c1b7c3eae..6cc9abcd7b3d 100644
--- a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
+++ b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h
@@ -12,7 +12,6 @@
#define PPC64_TLB_BATCH_NR 192
struct ppc64_tlb_batch {
- int active;
unsigned long index;
struct mm_struct *mm;
real_pte_t pte[PPC64_TLB_BATCH_NR];
@@ -26,8 +25,6 @@ extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
static inline void arch_enter_lazy_mmu_mode(void)
{
- struct ppc64_tlb_batch *batch;
-
if (radix_enabled())
return;
/*
@@ -35,8 +32,6 @@ static inline void arch_enter_lazy_mmu_mode(void)
* operating on kernel page tables.
*/
preempt_disable();
- batch = this_cpu_ptr(&ppc64_tlb_batch);
- batch->active = 1;
}
static inline void arch_flush_lazy_mmu_mode(void)
@@ -53,14 +48,10 @@ static inline void arch_flush_lazy_mmu_mode(void)
static inline void arch_leave_lazy_mmu_mode(void)
{
- struct ppc64_tlb_batch *batch;
-
if (radix_enabled())
return;
- batch = this_cpu_ptr(&ppc64_tlb_batch);
arch_flush_lazy_mmu_mode();
- batch->active = 0;
preempt_enable();
}
diff --git a/arch/powerpc/mm/book3s64/hash_tlb.c b/arch/powerpc/mm/book3s64/hash_tlb.c
index 787f7a0e27f0..fbdeb8981ae7 100644
--- a/arch/powerpc/mm/book3s64/hash_tlb.c
+++ b/arch/powerpc/mm/book3s64/hash_tlb.c
@@ -100,7 +100,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
* Check if we have an active batch on this CPU. If not, just
* flush now and return.
*/
- if (!batch->active) {
+ if (!is_lazy_mmu_mode_active()) {
flush_hash_page(vpn, rpte, psize, ssize, mm_is_thread_local(mm));
put_cpu_var(ppc64_tlb_batch);
return;
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 12/14] sparc/mm: replace batch->active with is_lazy_mmu_mode_active()
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (10 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 11/14] powerpc/mm: replace batch->active " Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 13/14] x86/xen: use lazy_mmu_state when context-switching Kevin Brodsky
` (2 subsequent siblings)
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86,
David Hildenbrand (Red Hat)
A per-CPU batch struct is activated when entering lazy MMU mode; its
lifetime is the same as the lazy MMU section (it is deactivated when
leaving the mode). Preemption is disabled in that interval to ensure
that the per-CPU reference remains valid.
The generic lazy_mmu layer now tracks whether a task is in lazy MMU
mode. We can therefore use the generic helper
is_lazy_mmu_mode_active() to tell whether a batch struct is active
instead of tracking it explicitly.
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/sparc/include/asm/tlbflush_64.h | 1 -
arch/sparc/mm/tlb.c | 9 +--------
2 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h
index 4e1036728e2f..6133306ba59a 100644
--- a/arch/sparc/include/asm/tlbflush_64.h
+++ b/arch/sparc/include/asm/tlbflush_64.h
@@ -12,7 +12,6 @@ struct tlb_batch {
unsigned int hugepage_shift;
struct mm_struct *mm;
unsigned long tlb_nr;
- unsigned long active;
unsigned long vaddrs[TLB_BATCH_NR];
};
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index 7b5dfcdb1243..3a852071d260 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -52,11 +52,7 @@ void flush_tlb_pending(void)
void arch_enter_lazy_mmu_mode(void)
{
- struct tlb_batch *tb;
-
preempt_disable();
- tb = this_cpu_ptr(&tlb_batch);
- tb->active = 1;
}
void arch_flush_lazy_mmu_mode(void)
@@ -69,10 +65,7 @@ void arch_flush_lazy_mmu_mode(void)
void arch_leave_lazy_mmu_mode(void)
{
- struct tlb_batch *tb = this_cpu_ptr(&tlb_batch);
-
arch_flush_lazy_mmu_mode();
- tb->active = 0;
preempt_enable();
}
@@ -93,7 +86,7 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
nr = 0;
}
- if (!tb->active) {
+ if (!is_lazy_mmu_mode_active()) {
flush_tsb_user_page(mm, vaddr, hugepage_shift);
global_flush_tlb_page(mm, vaddr);
goto out;
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 13/14] x86/xen: use lazy_mmu_state when context-switching
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (11 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 12/14] sparc/mm: " Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 14/14] mm: Add basic tests for lazy_mmu Kevin Brodsky
2025-12-15 16:52 ` [PATCH v6 00/14] Nesting support for lazy MMU mode Yeoreum Yun
14 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86,
David Hildenbrand (Red Hat)
We currently set a TIF flag when scheduling out a task that is in
lazy MMU mode, in order to restore it when the task is scheduled
again.
The generic lazy_mmu layer now tracks whether a task is in lazy MMU
mode in task_struct::lazy_mmu_state. We can therefore check that
state when switching to the new task, instead of using a separate
TIF flag.
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/x86/include/asm/thread_info.h | 4 +---
arch/x86/xen/enlighten_pv.c | 3 +--
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index e71e0e8362ed..0067684afb5b 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -100,8 +100,7 @@ struct thread_info {
#define TIF_FORCED_TF 24 /* true if TF in eflags artificially */
#define TIF_SINGLESTEP 25 /* reenable singlestep on user return*/
#define TIF_BLOCKSTEP 26 /* set when we want DEBUGCTLMSR_BTF */
-#define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */
-#define TIF_ADDR32 28 /* 32-bit address space on 64 bits */
+#define TIF_ADDR32 27 /* 32-bit address space on 64 bits */
#define _TIF_SSBD BIT(TIF_SSBD)
#define _TIF_SPEC_IB BIT(TIF_SPEC_IB)
@@ -114,7 +113,6 @@ struct thread_info {
#define _TIF_FORCED_TF BIT(TIF_FORCED_TF)
#define _TIF_BLOCKSTEP BIT(TIF_BLOCKSTEP)
#define _TIF_SINGLESTEP BIT(TIF_SINGLESTEP)
-#define _TIF_LAZY_MMU_UPDATES BIT(TIF_LAZY_MMU_UPDATES)
#define _TIF_ADDR32 BIT(TIF_ADDR32)
/* flags to check in __switch_to() */
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 4806cc28d7ca..98dbb6a61087 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -426,7 +426,6 @@ static void xen_start_context_switch(struct task_struct *prev)
if (this_cpu_read(xen_lazy_mode) == XEN_LAZY_MMU) {
arch_leave_lazy_mmu_mode();
- set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES);
}
enter_lazy(XEN_LAZY_CPU);
}
@@ -437,7 +436,7 @@ static void xen_end_context_switch(struct task_struct *next)
xen_mc_flush();
leave_lazy(XEN_LAZY_CPU);
- if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES))
+ if (__task_lazy_mmu_mode_active(next))
arch_enter_lazy_mmu_mode();
}
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v6 14/14] mm: Add basic tests for lazy_mmu
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (12 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 13/14] x86/xen: use lazy_mmu_state when context-switching Kevin Brodsky
@ 2025-12-15 15:03 ` Kevin Brodsky
2025-12-17 4:14 ` Andrew Morton
2025-12-15 16:52 ` [PATCH v6 00/14] Nesting support for lazy MMU mode Yeoreum Yun
14 siblings, 1 reply; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-15 15:03 UTC (permalink / raw)
To: linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
Add basic KUnit tests for the generic aspects of the lazy MMU mode:
ensure that it appears active when it should, depending on how
enable/disable and pause/resume pairs are nested.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
mm/Kconfig | 12 ++++++
mm/Makefile | 1 +
mm/tests/lazy_mmu_mode_kunit.c | 71 ++++++++++++++++++++++++++++++++++
3 files changed, 84 insertions(+)
create mode 100644 mm/tests/lazy_mmu_mode_kunit.c
diff --git a/mm/Kconfig b/mm/Kconfig
index 62073bd61544..ac48deb44884 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1471,6 +1471,18 @@ config ARCH_HAS_LAZY_MMU_MODE
MMU-related architectural state to be deferred until the mode is
exited. See <linux/pgtable.h> for details.
+config LAZY_MMU_MODE_KUNIT_TEST
+ tristate "KUnit tests for the lazy MMU mode" if !KUNIT_ALL_TESTS
+ depends on ARCH_HAS_LAZY_MMU_MODE
+ depends on KUNIT
+ default KUNIT_ALL_TESTS
+ help
+ Enable this option to check that the lazy MMU mode interface behaves
+ as expected. Only tests for the generic interface are included (not
+ architecture-specific behaviours).
+
+ If unsure, say N.
+
source "mm/damon/Kconfig"
endmenu
diff --git a/mm/Makefile b/mm/Makefile
index 2d0570a16e5b..9175f8cc6565 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -147,3 +147,4 @@ obj-$(CONFIG_SHRINKER_DEBUG) += shrinker_debug.o
obj-$(CONFIG_EXECMEM) += execmem.o
obj-$(CONFIG_TMPFS_QUOTA) += shmem_quota.o
obj-$(CONFIG_PT_RECLAIM) += pt_reclaim.o
+obj-$(CONFIG_LAZY_MMU_MODE_KUNIT_TEST) += tests/lazy_mmu_mode_kunit.o
diff --git a/mm/tests/lazy_mmu_mode_kunit.c b/mm/tests/lazy_mmu_mode_kunit.c
new file mode 100644
index 000000000000..2720eb995714
--- /dev/null
+++ b/mm/tests/lazy_mmu_mode_kunit.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <kunit/test.h>
+#include <linux/pgtable.h>
+
+static void expect_not_active(struct kunit *test)
+{
+ KUNIT_EXPECT_FALSE(test, is_lazy_mmu_mode_active());
+}
+
+static void expect_active(struct kunit *test)
+{
+ KUNIT_EXPECT_TRUE(test, is_lazy_mmu_mode_active());
+}
+
+static void lazy_mmu_mode_active(struct kunit *test)
+{
+ expect_not_active(test);
+
+ lazy_mmu_mode_enable();
+ expect_active(test);
+
+ {
+ /* Nested section */
+ lazy_mmu_mode_enable();
+ expect_active(test);
+
+ lazy_mmu_mode_disable();
+ expect_active(test);
+ }
+
+ {
+ /* Paused section */
+ lazy_mmu_mode_pause();
+ expect_not_active(test);
+
+ {
+ /* No effect (paused) */
+ lazy_mmu_mode_enable();
+ expect_not_active(test);
+
+ lazy_mmu_mode_disable();
+ expect_not_active(test);
+
+ lazy_mmu_mode_pause();
+ expect_not_active(test);
+
+ lazy_mmu_mode_resume();
+ expect_not_active(test);
+ }
+
+ lazy_mmu_mode_resume();
+ expect_active(test);
+ }
+
+ lazy_mmu_mode_disable();
+ expect_not_active(test);
+}
+
+static struct kunit_case lazy_mmu_mode_test_cases[] = {
+ KUNIT_CASE(lazy_mmu_mode_active),
+ {}
+};
+
+static struct kunit_suite lazy_mmu_mode_test_suite = {
+ .name = "lazy_mmu_mode",
+ .test_cases = lazy_mmu_mode_test_cases,
+};
+kunit_test_suite(lazy_mmu_mode_test_suite);
+
+MODULE_DESCRIPTION("Tests for the lazy MMU mode");
+MODULE_LICENSE("GPL");
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH v6 00/14] Nesting support for lazy MMU mode
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
` (13 preceding siblings ...)
2025-12-15 15:03 ` [PATCH v6 14/14] mm: Add basic tests for lazy_mmu Kevin Brodsky
@ 2025-12-15 16:52 ` Yeoreum Yun
14 siblings, 0 replies; 29+ messages in thread
From: Yeoreum Yun @ 2025-12-15 16:52 UTC (permalink / raw)
To: Kevin Brodsky
Cc: linux-mm, linux-kernel, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ritesh Harjani (IBM), Ryan Roberts,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, linux-arm-kernel, linuxppc-dev,
sparclinux, xen-devel, x86
> When the lazy MMU mode was introduced eons ago, it wasn't made clear
> whether such a sequence was legal:
>
> arch_enter_lazy_mmu_mode()
> ...
> arch_enter_lazy_mmu_mode()
> ...
> arch_leave_lazy_mmu_mode()
> ...
> arch_leave_lazy_mmu_mode()
>
> It seems fair to say that nested calls to
> arch_{enter,leave}_lazy_mmu_mode() were not expected, and most
> architectures never explicitly supported it.
>
> Nesting does in fact occur in certain configurations, and avoiding it
> has proved difficult. This series therefore enables lazy_mmu sections to
> nest, on all architectures.
>
> Nesting is handled using a counter in task_struct (patch 8), like other
> stateless APIs such as pagefault_{disable,enable}(). This is fully
> handled in a new generic layer in <linux/pgtable.h>; the arch_* API
> remains unchanged. A new pair of calls, lazy_mmu_mode_{pause,resume}(),
> is also introduced to allow functions that are called with the lazy MMU
> mode enabled to temporarily pause it, regardless of nesting.
>
> An arch now opts in to using the lazy MMU mode by selecting
> CONFIG_ARCH_LAZY_MMU; this is more appropriate now that we have a
> generic API, especially with state conditionally added to task_struct.
>
> ---
>
> Background: Ryan Roberts' series from March [1] attempted to prevent
> nesting from ever occurring, and mostly succeeded. Unfortunately, a
> corner case (DEBUG_PAGEALLOC) may still cause nesting to occur on arm64.
> Ryan proposed [2] to address that corner case at the generic level but
> this approach received pushback; [3] then attempted to solve the issue
> on arm64 only, but it was deemed too fragile.
>
> It feels generally difficult to guarantee that lazy_mmu sections don't
> nest, because callers of various standard mm functions do not know if
> the function uses lazy_mmu itself.
>
> The overall approach in v3/v4 is very close to what David Hildenbrand
> proposed on v2 [4].
>
> Unlike in v1/v2, no special provision is made for architectures to
> save/restore extra state when entering/leaving the mode. Based on the
> discussions so far, this does not seem to be required - an arch can
> store any relevant state in thread_struct during arch_enter() and
> restore it in arch_leave(). Nesting is not a concern as these functions
> are only called at the top level, not in nested sections.
>
> The introduction of a generic layer, and tracking of the lazy MMU state
> in task_struct, also allows to streamline the arch callbacks - this
> series removes 67 lines from arch/.
>
> Patch overview:
>
> * Patch 1: cleanup - avoids having to deal with the powerpc
> context-switching code
>
> * Patch 2-4: prepare arch_flush_lazy_mmu_mode() to be called from the
> generic layer (patch 9)
>
> * Patch 5: documentation clarification (not directly related to the
> changes in this series)
>
> * Patch 6-7: new API + CONFIG_ARCH_LAZY_MMU
>
> * Patch 8: ensure correctness in interrupt context
>
> * Patch 9: nesting support
>
> * Patch 10-13: replace arch-specific tracking of lazy MMU mode with
> generic API
>
> * Patch 14: basic tests to ensure that the state added in patch 9 is
> tracked correctly
>
> This series has been tested by running the mm kselftests on arm64 with
> DEBUG_VM, DEBUG_PAGEALLOC, KFENCE and KASAN. Extensive testing on
> powerpc was also kindly provided by Venkat Rao Bagalkote [5]. It was
> build-tested on other architectures (with and without XEN_PV on x86).
>
> - Kevin
>
> [1] https://lore.kernel.org/all/20250303141542.3371656-1-ryan.roberts@arm.com/
> [2] https://lore.kernel.org/all/20250530140446.2387131-1-ryan.roberts@arm.com/
> [3] https://lore.kernel.org/all/20250606135654.178300-1-ryan.roberts@arm.com/
> [4] https://lore.kernel.org/all/ef343405-c394-4763-a79f-21381f217b6c@redhat.com/
> [5] https://lore.kernel.org/all/94889730-1AEF-458F-B623-04092C0D6819@linux.ibm.com/
> ---
> Changelog
>
> v5..v6:
>
> - Rebased on v6.19-rc1
> - Overall: no functional change
> - Patch 5: new patch clarifying that generic code may not sleep while in lazy
> MMU mode [Alexander Gordeev]
> - Patch 6: added description for the ARCH_HAS_LAZY_MMU_MODE option
> [Anshuman Khandual]
> - Patch 9: rename in_lazy_mmu_mode() to is_lazy_mmu_mode_active() [Alexander]
> - Patch 14: new patch with basic KUnit tests [Anshuman]
> - Collected R-b/A-b/T-b tags
>
> v5: https://lore.kernel.org/all/20251124132228.622678-1-kevin.brodsky@arm.com/
>
> v4..v5:
>
> - Rebased on mm-unstable
> - Patch 3: added missing radix_enabled() check in arch_flush()
> [Ritesh Harjani]
> - Patch 6: declare arch_flush_lazy_mmu_mode() as static inline on x86
> [Ryan Roberts]
> - Patch 7 (formerly 12): moved before patch 8 to ensure correctness in
> interrupt context [Ryan]. The diffs in in_lazy_mmu_mode() and
> queue_pte_barriers() are moved to patch 8 and 9 resp.
> - Patch 8:
> * Removed all restrictions regarding lazy_mmu_mode_{pause,resume}().
> They may now be called even when lazy MMU isn't enabled, and
> any call to lazy_mmu_mode_* may be made while paused (such calls
> will be ignored). [David, Ryan]
> * lazy_mmu_state.{nesting_level,active} are replaced with
> {enable_count,pause_count} to track arbitrary nesting of both
> enable/disable and pause/resume [Ryan]
> * Added __task_lazy_mmu_mode_active() for use in patch 12 [David]
> * Added documentation for all the functions [Ryan]
> - Patch 9: keep existing test + set TIF_LAZY_MMU_PENDING instead of
> atomic RMW [David, Ryan]
> - Patch 12: use __task_lazy_mmu_mode_active() instead of accessing
> lazy_mmu_state directly [David]
> - Collected R-b/A-b tags
>
> v4: https://lore.kernel.org/all/20251029100909.3381140-1-kevin.brodsky@arm.com/
>
> v3..v4:
>
> - Patch 2: restored ordering of preempt_{disable,enable}() [Dave Hansen]
> - Patch 5 onwards: s/ARCH_LAZY_MMU/ARCH_HAS_LAZY_MMU_MODE/ [Mike Rapoport]
> - Patch 7: renamed lazy_mmu_state members, removed VM_BUG_ON(),
> reordered writes to lazy_mmu_state members [David Hildenbrand]
> - Dropped patch 13 as it doesn't seem justified [David H]
> - Various improvements to commit messages [David H]
>
> v3: https://lore.kernel.org/all/20251015082727.2395128-1-kevin.brodsky@arm.com/
>
> v2..v3:
>
> - Full rewrite; dropped all Acked-by/Reviewed-by.
> - Rebased on v6.18-rc1.
>
> v2: https://lore.kernel.org/all/20250908073931.4159362-1-kevin.brodsky@arm.com/
>
> v1..v2:
> - Rebased on mm-unstable.
> - Patch 2: handled new calls to enter()/leave(), clarified how the "flush"
> pattern (leave() followed by enter()) is handled.
> - Patch 5,6: removed unnecessary local variable [Alexander Gordeev's
> suggestion].
> - Added Mike Rapoport's Acked-by.
>
> v1: https://lore.kernel.org/all/20250904125736.3918646-1-kevin.brodsky@arm.com/
> ---
> Cc: Alexander Gordeev <agordeev@linux.ibm.com>
> Cc: Andreas Larsson <andreas@gaisler.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Anshuman Khandual <anshuman.khandual@arm.com>
> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Jann Horn <jannh@google.com>
> Cc: Juergen Gross <jgross@suse.com>
> Cc: "Liam R. Howlett" <Liam.Howlett@oracle.com>
> Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Mike Rapoport <rppt@kernel.org>
> Cc: Nicholas Piggin <npiggin@gmail.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
> Cc: Ryan Roberts <ryan.roberts@arm.com>
> Cc: Suren Baghdasaryan <surenb@google.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
> Cc: Vlastimil Babka <vbabka@suse.cz>
> Cc: Will Deacon <will@kernel.org>
> Cc: Yeoreum Yun <yeoreum.yun@arm.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: sparclinux@vger.kernel.org
> Cc: xen-devel@lists.xenproject.org
> Cc: x86@kernel.org
> ---
> Alexander Gordeev (1):
> powerpc/64s: Do not re-activate batched TLB flush
>
> Kevin Brodsky (13):
> x86/xen: simplify flush_lazy_mmu()
> powerpc/mm: implement arch_flush_lazy_mmu_mode()
> sparc/mm: implement arch_flush_lazy_mmu_mode()
> mm: clarify lazy_mmu sleeping constraints
> mm: introduce CONFIG_ARCH_HAS_LAZY_MMU_MODE
> mm: introduce generic lazy_mmu helpers
> mm: bail out of lazy_mmu_mode_* in interrupt context
> mm: enable lazy_mmu sections to nest
> arm64: mm: replace TIF_LAZY_MMU with is_lazy_mmu_mode_active()
> powerpc/mm: replace batch->active with is_lazy_mmu_mode_active()
> sparc/mm: replace batch->active with is_lazy_mmu_mode_active()
> x86/xen: use lazy_mmu_state when context-switching
> mm: Add basic tests for lazy_mmu
>
> arch/arm64/Kconfig | 1 +
> arch/arm64/include/asm/pgtable.h | 41 +----
> arch/arm64/include/asm/thread_info.h | 3 +-
> arch/arm64/mm/mmu.c | 8 +-
> arch/arm64/mm/pageattr.c | 4 +-
> .../include/asm/book3s/64/tlbflush-hash.h | 20 +--
> arch/powerpc/include/asm/thread_info.h | 2 -
> arch/powerpc/kernel/process.c | 25 ---
> arch/powerpc/mm/book3s64/hash_tlb.c | 10 +-
> arch/powerpc/mm/book3s64/subpage_prot.c | 4 +-
> arch/powerpc/platforms/Kconfig.cputype | 1 +
> arch/sparc/Kconfig | 1 +
> arch/sparc/include/asm/tlbflush_64.h | 5 +-
> arch/sparc/mm/tlb.c | 14 +-
> arch/x86/Kconfig | 1 +
> arch/x86/boot/compressed/misc.h | 1 +
> arch/x86/boot/startup/sme.c | 1 +
> arch/x86/include/asm/paravirt.h | 1 -
> arch/x86/include/asm/pgtable.h | 1 +
> arch/x86/include/asm/thread_info.h | 4 +-
> arch/x86/xen/enlighten_pv.c | 3 +-
> arch/x86/xen/mmu_pv.c | 6 +-
> fs/proc/task_mmu.c | 4 +-
> include/linux/mm_types_task.h | 5 +
> include/linux/pgtable.h | 158 +++++++++++++++++-
> include/linux/sched.h | 45 +++++
> mm/Kconfig | 19 +++
> mm/Makefile | 1 +
> mm/kasan/shadow.c | 8 +-
> mm/madvise.c | 18 +-
> mm/memory.c | 16 +-
> mm/migrate_device.c | 8 +-
> mm/mprotect.c | 4 +-
> mm/mremap.c | 4 +-
> mm/tests/lazy_mmu_mode_kunit.c | 71 ++++++++
> mm/userfaultfd.c | 4 +-
> mm/vmalloc.c | 12 +-
> mm/vmscan.c | 12 +-
> 38 files changed, 380 insertions(+), 166 deletions(-)
> create mode 100644 mm/tests/lazy_mmu_mode_kunit.c
>
>
> base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
> --
> 2.51.2
All of these look good to me.
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
--
Sincerely,
Yeoreum Yun
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v6 03/14] powerpc/mm: implement arch_flush_lazy_mmu_mode()
2025-12-15 15:03 ` [PATCH v6 03/14] powerpc/mm: implement arch_flush_lazy_mmu_mode() Kevin Brodsky
@ 2025-12-16 5:14 ` Ritesh Harjani
0 siblings, 0 replies; 29+ messages in thread
From: Ritesh Harjani @ 2025-12-16 5:14 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm
Cc: linux-kernel, Kevin Brodsky, Alexander Gordeev, Andreas Larsson,
Andrew Morton, Anshuman Khandual, Boris Ostrovsky,
Borislav Petkov, Catalin Marinas, Christophe Leroy, Dave Hansen,
David Hildenbrand, David S. Miller, David Woodhouse,
H. Peter Anvin, Ingo Molnar, Jann Horn, Juergen Gross,
Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
Michael Ellerman, Michal Hocko, Mike Rapoport, Nicholas Piggin,
Peter Zijlstra, Ryan Roberts, Suren Baghdasaryan, Thomas Gleixner,
Venkat Rao Bagalkote, Vlastimil Babka, Will Deacon, Yeoreum Yun,
linux-arm-kernel, linuxppc-dev, sparclinux, xen-devel, x86
Kevin Brodsky <kevin.brodsky@arm.com> writes:
> Upcoming changes to the lazy_mmu API will cause
> arch_flush_lazy_mmu_mode() to be called when leaving a nested
> lazy_mmu section.
>
> Move the relevant logic from arch_leave_lazy_mmu_mode() to
> arch_flush_lazy_mmu_mode() and have the former call the latter. The
> radix_enabled() check is required in both as
> arch_flush_lazy_mmu_mode() will be called directly from the generic
> layer in a subsequent patch.
>
> Note: the additional this_cpu_ptr() and radix_enabled() calls on the
> arch_leave_lazy_mmu_mode() path will be removed in a subsequent
> patch.
>
> Acked-by: David Hildenbrand <david@redhat.com>
> Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> .../powerpc/include/asm/book3s/64/tlbflush-hash.h | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
Sorry I was away for a while.
Thanks for taking care of the radix path as we had discussed previously
here [1].
[1]: https://lore.kernel.org/all/87jz044xn4.ritesh.list@gmail.com/
The change looks good to me. So, please feel free to add:
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v6 14/14] mm: Add basic tests for lazy_mmu
2025-12-15 15:03 ` [PATCH v6 14/14] mm: Add basic tests for lazy_mmu Kevin Brodsky
@ 2025-12-17 4:14 ` Andrew Morton
2025-12-17 9:26 ` Kevin Brodsky
` (2 more replies)
0 siblings, 3 replies; 29+ messages in thread
From: Andrew Morton @ 2025-12-17 4:14 UTC (permalink / raw)
To: Kevin Brodsky
Cc: linux-mm, linux-kernel, Alexander Gordeev, Andreas Larsson,
Anshuman Khandual, Boris Ostrovsky, Borislav Petkov,
Catalin Marinas, Christophe Leroy, Dave Hansen, David Hildenbrand,
David S. Miller, David Woodhouse, H. Peter Anvin, Ingo Molnar,
Jann Horn, Juergen Gross, Liam R. Howlett, Lorenzo Stoakes,
Madhavan Srinivasan, Michael Ellerman, Michal Hocko,
Mike Rapoport, Nicholas Piggin, Peter Zijlstra,
Ritesh Harjani (IBM), Ryan Roberts, Suren Baghdasaryan,
Thomas Gleixner, Venkat Rao Bagalkote, Vlastimil Babka,
Will Deacon, Yeoreum Yun, linux-arm-kernel, linuxppc-dev,
sparclinux, xen-devel, x86
On Mon, 15 Dec 2025 15:03:23 +0000 Kevin Brodsky <kevin.brodsky@arm.com> wrote:
> Add basic KUnit tests for the generic aspects of the lazy MMU mode:
> ensure that it appears active when it should, depending on how
> enable/disable and pause/resume pairs are nested.
I needed this for powerpc allmodconfig;
--- a/arch/powerpc/mm/book3s64/hash_tlb.c~mm-add-basic-tests-for-lazy_mmu-fix
+++ a/arch/powerpc/mm/book3s64/hash_tlb.c
@@ -30,6 +30,7 @@
#include <trace/events/thp.h>
DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
+EXPORT_SYMBOL_GPL(ppc64_tlb_batch);
/*
* A linux PTE was changed and the corresponding hash table entry
@@ -154,6 +155,7 @@ void __flush_tlb_pending(struct ppc64_tl
flush_hash_range(i, local);
batch->index = 0;
}
+EXPORT_SYMBOL_GPL(__flush_tlb_pending);
void hash__tlb_flush(struct mmu_gather *tlb)
{
_
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v6 14/14] mm: Add basic tests for lazy_mmu
2025-12-17 4:14 ` Andrew Morton
@ 2025-12-17 9:26 ` Kevin Brodsky
2025-12-17 10:01 ` Ryan Roberts
2025-12-17 16:38 ` [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests Kevin Brodsky
2025-12-17 16:38 ` [PATCH] mm: Add basic tests for lazy_mmu - fix for powerpc Kevin Brodsky
2 siblings, 1 reply; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-17 9:26 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, linux-kernel, Alexander Gordeev, Andreas Larsson,
Anshuman Khandual, Boris Ostrovsky, Borislav Petkov,
Catalin Marinas, Christophe Leroy, Dave Hansen, David Hildenbrand,
David S. Miller, David Woodhouse, H. Peter Anvin, Ingo Molnar,
Jann Horn, Juergen Gross, Liam R. Howlett, Lorenzo Stoakes,
Madhavan Srinivasan, Michael Ellerman, Michal Hocko,
Mike Rapoport, Nicholas Piggin, Peter Zijlstra,
Ritesh Harjani (IBM), Ryan Roberts, Suren Baghdasaryan,
Thomas Gleixner, Venkat Rao Bagalkote, Vlastimil Babka,
Will Deacon, Yeoreum Yun, linux-arm-kernel, linuxppc-dev,
sparclinux, xen-devel, x86
On 17/12/2025 05:14, Andrew Morton wrote:
> On Mon, 15 Dec 2025 15:03:23 +0000 Kevin Brodsky <kevin.brodsky@arm.com> wrote:
>
>> Add basic KUnit tests for the generic aspects of the lazy MMU mode:
>> ensure that it appears active when it should, depending on how
>> enable/disable and pause/resume pairs are nested.
> I needed this for powerpc allmodconfig;
>
> --- a/arch/powerpc/mm/book3s64/hash_tlb.c~mm-add-basic-tests-for-lazy_mmu-fix
> +++ a/arch/powerpc/mm/book3s64/hash_tlb.c
> @@ -30,6 +30,7 @@
> #include <trace/events/thp.h>
>
> DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
> +EXPORT_SYMBOL_GPL(ppc64_tlb_batch);
>
> /*
> * A linux PTE was changed and the corresponding hash table entry
> @@ -154,6 +155,7 @@ void __flush_tlb_pending(struct ppc64_tl
> flush_hash_range(i, local);
> batch->index = 0;
> }
> +EXPORT_SYMBOL_GPL(__flush_tlb_pending);
>
> void hash__tlb_flush(struct mmu_gather *tlb)
> {
> _
Oh indeed I hadn't considered that arch_{enter,leave}_lazy_mmu_mode()
refer to those symbols on powerpc... Maybe a bit overkill to export
those just for a test module, but I'm not sure there's a good
alternative. Forcing LAZY_MMU_MODE_KUNIT_TEST=y is ugly as it would also
force KUNIT=y. Alternatively we could depend on !PPC, not pretty either.
- Kevin
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v6 14/14] mm: Add basic tests for lazy_mmu
2025-12-17 9:26 ` Kevin Brodsky
@ 2025-12-17 10:01 ` Ryan Roberts
2025-12-17 15:37 ` Kevin Brodsky
2025-12-17 15:46 ` Ritesh Harjani
0 siblings, 2 replies; 29+ messages in thread
From: Ryan Roberts @ 2025-12-17 10:01 UTC (permalink / raw)
To: Kevin Brodsky, Andrew Morton
Cc: linux-mm, linux-kernel, Alexander Gordeev, Andreas Larsson,
Anshuman Khandual, Boris Ostrovsky, Borislav Petkov,
Catalin Marinas, Christophe Leroy, Dave Hansen, David Hildenbrand,
David S. Miller, David Woodhouse, H. Peter Anvin, Ingo Molnar,
Jann Horn, Juergen Gross, Liam R. Howlett, Lorenzo Stoakes,
Madhavan Srinivasan, Michael Ellerman, Michal Hocko,
Mike Rapoport, Nicholas Piggin, Peter Zijlstra,
Ritesh Harjani (IBM), Suren Baghdasaryan, Thomas Gleixner,
Venkat Rao Bagalkote, Vlastimil Babka, Will Deacon, Yeoreum Yun,
linux-arm-kernel, linuxppc-dev, sparclinux, xen-devel, x86
On 17/12/2025 09:26, Kevin Brodsky wrote:
> On 17/12/2025 05:14, Andrew Morton wrote:
>> On Mon, 15 Dec 2025 15:03:23 +0000 Kevin Brodsky <kevin.brodsky@arm.com> wrote:
>>
>>> Add basic KUnit tests for the generic aspects of the lazy MMU mode:
>>> ensure that it appears active when it should, depending on how
>>> enable/disable and pause/resume pairs are nested.
>> I needed this for powerpc allmodconfig;
>>
>> --- a/arch/powerpc/mm/book3s64/hash_tlb.c~mm-add-basic-tests-for-lazy_mmu-fix
>> +++ a/arch/powerpc/mm/book3s64/hash_tlb.c
>> @@ -30,6 +30,7 @@
>> #include <trace/events/thp.h>
>>
>> DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
>> +EXPORT_SYMBOL_GPL(ppc64_tlb_batch);
>>
>> /*
>> * A linux PTE was changed and the corresponding hash table entry
>> @@ -154,6 +155,7 @@ void __flush_tlb_pending(struct ppc64_tl
>> flush_hash_range(i, local);
>> batch->index = 0;
>> }
>> +EXPORT_SYMBOL_GPL(__flush_tlb_pending);
>>
>> void hash__tlb_flush(struct mmu_gather *tlb)
>> {
>> _
>
> Oh indeed I hadn't considered that arch_{enter,leave}_lazy_mmu_mode()
> refer to those symbols on powerpc... Maybe a bit overkill to export
> those just for a test module, but I'm not sure there's a good
> alternative. Forcing LAZY_MMU_MODE_KUNIT_TEST=y is ugly as it would also
> force KUNIT=y. Alternatively we could depend on !PPC, not pretty either.
Does EXPORT_SYMBOL_IF_KUNIT() help?
>
> - Kevin
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v6 14/14] mm: Add basic tests for lazy_mmu
2025-12-17 10:01 ` Ryan Roberts
@ 2025-12-17 15:37 ` Kevin Brodsky
2025-12-17 15:46 ` Ritesh Harjani
1 sibling, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-17 15:37 UTC (permalink / raw)
To: Ryan Roberts, Andrew Morton
Cc: linux-mm, linux-kernel, Alexander Gordeev, Andreas Larsson,
Anshuman Khandual, Boris Ostrovsky, Borislav Petkov,
Catalin Marinas, Christophe Leroy, Dave Hansen, David Hildenbrand,
David S. Miller, David Woodhouse, H. Peter Anvin, Ingo Molnar,
Jann Horn, Juergen Gross, Liam R. Howlett, Lorenzo Stoakes,
Madhavan Srinivasan, Michael Ellerman, Michal Hocko,
Mike Rapoport, Nicholas Piggin, Peter Zijlstra,
Ritesh Harjani (IBM), Suren Baghdasaryan, Thomas Gleixner,
Venkat Rao Bagalkote, Vlastimil Babka, Will Deacon, Yeoreum Yun,
linux-arm-kernel, linuxppc-dev, sparclinux, xen-devel, x86
On 17/12/2025 11:01, Ryan Roberts wrote:
> On 17/12/2025 09:26, Kevin Brodsky wrote:
>> On 17/12/2025 05:14, Andrew Morton wrote:
>>> On Mon, 15 Dec 2025 15:03:23 +0000 Kevin Brodsky <kevin.brodsky@arm.com> wrote:
>>>
>>>> Add basic KUnit tests for the generic aspects of the lazy MMU mode:
>>>> ensure that it appears active when it should, depending on how
>>>> enable/disable and pause/resume pairs are nested.
>>> I needed this for powerpc allmodconfig;
>>>
>>> --- a/arch/powerpc/mm/book3s64/hash_tlb.c~mm-add-basic-tests-for-lazy_mmu-fix
>>> +++ a/arch/powerpc/mm/book3s64/hash_tlb.c
>>> @@ -30,6 +30,7 @@
>>> #include <trace/events/thp.h>
>>>
>>> DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
>>> +EXPORT_SYMBOL_GPL(ppc64_tlb_batch);
>>>
>>> /*
>>> * A linux PTE was changed and the corresponding hash table entry
>>> @@ -154,6 +155,7 @@ void __flush_tlb_pending(struct ppc64_tl
>>> flush_hash_range(i, local);
>>> batch->index = 0;
>>> }
>>> +EXPORT_SYMBOL_GPL(__flush_tlb_pending);
>>>
>>> void hash__tlb_flush(struct mmu_gather *tlb)
>>> {
>>> _
>> Oh indeed I hadn't considered that arch_{enter,leave}_lazy_mmu_mode()
>> refer to those symbols on powerpc... Maybe a bit overkill to export
>> those just for a test module, but I'm not sure there's a good
>> alternative. Forcing LAZY_MMU_MODE_KUNIT_TEST=y is ugly as it would also
>> force KUNIT=y. Alternatively we could depend on !PPC, not pretty either.
> Does EXPORT_SYMBOL_IF_KUNIT() help?
It most certainly would, I didn't know about that one, thanks!
- Kevin
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v6 14/14] mm: Add basic tests for lazy_mmu
2025-12-17 10:01 ` Ryan Roberts
2025-12-17 15:37 ` Kevin Brodsky
@ 2025-12-17 15:46 ` Ritesh Harjani
2025-12-17 16:10 ` Kevin Brodsky
1 sibling, 1 reply; 29+ messages in thread
From: Ritesh Harjani @ 2025-12-17 15:46 UTC (permalink / raw)
To: Ryan Roberts, Kevin Brodsky, Andrew Morton
Cc: linux-mm, linux-kernel, Alexander Gordeev, Andreas Larsson,
Anshuman Khandual, Boris Ostrovsky, Borislav Petkov,
Catalin Marinas, Christophe Leroy, Dave Hansen, David Hildenbrand,
David S. Miller, David Woodhouse, H. Peter Anvin, Ingo Molnar,
Jann Horn, Juergen Gross, Liam R. Howlett, Lorenzo Stoakes,
Madhavan Srinivasan, Michael Ellerman, Michal Hocko,
Mike Rapoport, Nicholas Piggin, Peter Zijlstra,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
Ryan Roberts <ryan.roberts@arm.com> writes:
> On 17/12/2025 09:26, Kevin Brodsky wrote:
>> On 17/12/2025 05:14, Andrew Morton wrote:
>>> On Mon, 15 Dec 2025 15:03:23 +0000 Kevin Brodsky <kevin.brodsky@arm.com> wrote:
>>>
>>>> Add basic KUnit tests for the generic aspects of the lazy MMU mode:
>>>> ensure that it appears active when it should, depending on how
>>>> enable/disable and pause/resume pairs are nested.
>>> I needed this for powerpc allmodconfig;
>>>
>>> --- a/arch/powerpc/mm/book3s64/hash_tlb.c~mm-add-basic-tests-for-lazy_mmu-fix
>>> +++ a/arch/powerpc/mm/book3s64/hash_tlb.c
>>> @@ -30,6 +30,7 @@
>>> #include <trace/events/thp.h>
>>>
>>> DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
>>> +EXPORT_SYMBOL_GPL(ppc64_tlb_batch);
>>>
>>> /*
>>> * A linux PTE was changed and the corresponding hash table entry
>>> @@ -154,6 +155,7 @@ void __flush_tlb_pending(struct ppc64_tl
>>> flush_hash_range(i, local);
>>> batch->index = 0;
>>> }
>>> +EXPORT_SYMBOL_GPL(__flush_tlb_pending);
>>>
>>> void hash__tlb_flush(struct mmu_gather *tlb)
>>> {
>>> _
>>
>> Oh indeed I hadn't considered that arch_{enter,leave}_lazy_mmu_mode()
>> refer to those symbols on powerpc... Maybe a bit overkill to export
>> those just for a test module, but I'm not sure there's a good
>> alternative. Forcing LAZY_MMU_MODE_KUNIT_TEST=y is ugly as it would also
>> force KUNIT=y. Alternatively we could depend on !PPC, not pretty either.
>
> Does EXPORT_SYMBOL_IF_KUNIT() help?
>
yes, that make sense. Thanks for the suggestion!
I guess we will need a diff like this in that case -
diff --git a/arch/powerpc/mm/book3s64/hash_tlb.c b/arch/powerpc/mm/book3s64/hash_tlb.c
index fbdeb8981ae7..ec2941cec815 100644
--- a/arch/powerpc/mm/book3s64/hash_tlb.c
+++ b/arch/powerpc/mm/book3s64/hash_tlb.c
@@ -25,11 +25,12 @@
#include <asm/tlb.h>
#include <asm/bug.h>
#include <asm/pte-walk.h>
-
+#include <kunit/visibility.h>
#include <trace/events/thp.h>
DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
+EXPORT_SYMBOL_IF_KUNIT(ppc64_tlb_batch);
/*
* A linux PTE was changed and the corresponding hash table entry
@@ -154,6 +155,7 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
flush_hash_range(i, local);
batch->index = 0;
}
+EXPORT_SYMBOL_IF_KUNIT(__flush_tlb_pending);
void hash__tlb_flush(struct mmu_gather *tlb)
{
diff --git a/mm/tests/lazy_mmu_mode_kunit.c b/mm/tests/lazy_mmu_mode_kunit.c
index 2720eb995714..340d7cda9096 100644
--- a/mm/tests/lazy_mmu_mode_kunit.c
+++ b/mm/tests/lazy_mmu_mode_kunit.c
@@ -69,3 +69,4 @@ kunit_test_suite(lazy_mmu_mode_test_suite);
MODULE_DESCRIPTION("Tests for the lazy MMU mode");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
-ritesh
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH v6 14/14] mm: Add basic tests for lazy_mmu
2025-12-17 15:46 ` Ritesh Harjani
@ 2025-12-17 16:10 ` Kevin Brodsky
0 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-17 16:10 UTC (permalink / raw)
To: Ritesh Harjani (IBM), Ryan Roberts, Andrew Morton
Cc: linux-mm, linux-kernel, Alexander Gordeev, Andreas Larsson,
Anshuman Khandual, Boris Ostrovsky, Borislav Petkov,
Catalin Marinas, Christophe Leroy, Dave Hansen, David Hildenbrand,
David S. Miller, David Woodhouse, H. Peter Anvin, Ingo Molnar,
Jann Horn, Juergen Gross, Liam R. Howlett, Lorenzo Stoakes,
Madhavan Srinivasan, Michael Ellerman, Michal Hocko,
Mike Rapoport, Nicholas Piggin, Peter Zijlstra,
Suren Baghdasaryan, Thomas Gleixner, Venkat Rao Bagalkote,
Vlastimil Babka, Will Deacon, Yeoreum Yun, linux-arm-kernel,
linuxppc-dev, sparclinux, xen-devel, x86
On 17/12/2025 16:46, Ritesh Harjani (IBM) wrote:
> Ryan Roberts <ryan.roberts@arm.com> writes:
>
>> On 17/12/2025 09:26, Kevin Brodsky wrote:
>>> On 17/12/2025 05:14, Andrew Morton wrote:
>>>> On Mon, 15 Dec 2025 15:03:23 +0000 Kevin Brodsky <kevin.brodsky@arm.com> wrote:
>>>>
>>>>> Add basic KUnit tests for the generic aspects of the lazy MMU mode:
>>>>> ensure that it appears active when it should, depending on how
>>>>> enable/disable and pause/resume pairs are nested.
>>>> I needed this for powerpc allmodconfig;
>>>>
>>>> --- a/arch/powerpc/mm/book3s64/hash_tlb.c~mm-add-basic-tests-for-lazy_mmu-fix
>>>> +++ a/arch/powerpc/mm/book3s64/hash_tlb.c
>>>> @@ -30,6 +30,7 @@
>>>> #include <trace/events/thp.h>
>>>>
>>>> DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
>>>> +EXPORT_SYMBOL_GPL(ppc64_tlb_batch);
>>>>
>>>> /*
>>>> * A linux PTE was changed and the corresponding hash table entry
>>>> @@ -154,6 +155,7 @@ void __flush_tlb_pending(struct ppc64_tl
>>>> flush_hash_range(i, local);
>>>> batch->index = 0;
>>>> }
>>>> +EXPORT_SYMBOL_GPL(__flush_tlb_pending);
>>>>
>>>> void hash__tlb_flush(struct mmu_gather *tlb)
>>>> {
>>>> _
>>> Oh indeed I hadn't considered that arch_{enter,leave}_lazy_mmu_mode()
>>> refer to those symbols on powerpc... Maybe a bit overkill to export
>>> those just for a test module, but I'm not sure there's a good
>>> alternative. Forcing LAZY_MMU_MODE_KUNIT_TEST=y is ugly as it would also
>>> force KUNIT=y. Alternatively we could depend on !PPC, not pretty either.
>> Does EXPORT_SYMBOL_IF_KUNIT() help?
>>
> yes, that make sense. Thanks for the suggestion!
> I guess we will need a diff like this in that case -
>
>
> diff --git a/arch/powerpc/mm/book3s64/hash_tlb.c b/arch/powerpc/mm/book3s64/hash_tlb.c
> index fbdeb8981ae7..ec2941cec815 100644
> --- a/arch/powerpc/mm/book3s64/hash_tlb.c
> +++ b/arch/powerpc/mm/book3s64/hash_tlb.c
> @@ -25,11 +25,12 @@
> #include <asm/tlb.h>
> #include <asm/bug.h>
> #include <asm/pte-walk.h>
> -
> +#include <kunit/visibility.h>
>
> #include <trace/events/thp.h>
>
> DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
> +EXPORT_SYMBOL_IF_KUNIT(ppc64_tlb_batch);
>
> /*
> * A linux PTE was changed and the corresponding hash table entry
> @@ -154,6 +155,7 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
> flush_hash_range(i, local);
> batch->index = 0;
> }
> +EXPORT_SYMBOL_IF_KUNIT(__flush_tlb_pending);
>
> void hash__tlb_flush(struct mmu_gather *tlb)
> {
> diff --git a/mm/tests/lazy_mmu_mode_kunit.c b/mm/tests/lazy_mmu_mode_kunit.c
> index 2720eb995714..340d7cda9096 100644
> --- a/mm/tests/lazy_mmu_mode_kunit.c
> +++ b/mm/tests/lazy_mmu_mode_kunit.c
> @@ -69,3 +69,4 @@ kunit_test_suite(lazy_mmu_mode_test_suite);
>
> MODULE_DESCRIPTION("Tests for the lazy MMU mode");
> MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
Indeed, that's pretty much what I was about to send :)
- Kevin
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests
2025-12-17 4:14 ` Andrew Morton
2025-12-17 9:26 ` Kevin Brodsky
@ 2025-12-17 16:38 ` Kevin Brodsky
2025-12-17 16:45 ` Ritesh Harjani
2025-12-21 23:42 ` kernel test robot
2025-12-17 16:38 ` [PATCH] mm: Add basic tests for lazy_mmu - fix for powerpc Kevin Brodsky
2 siblings, 2 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-17 16:38 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, Ryan Roberts, Ritesh Harjani, linux-mm,
linuxppc-dev, Kevin Brodsky
Upcoming KUnit tests will call lazy_mmu_mode_{enable,disable}.
These tests may be built as a module, and because of inlining this
means that symbols referenced by arch_{enter,leave}_lazy_mmu_mode
need to be exported.
Suggested-by: Ryan Roberts <ryan.roberts@arm.com>
Suggested-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
Andrew, please add this patch just before the last patch in the series
("mm: Add basic tests for lazy_mmu"). Thanks!
---
arch/powerpc/mm/book3s64/hash_tlb.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/mm/book3s64/hash_tlb.c b/arch/powerpc/mm/book3s64/hash_tlb.c
index fbdeb8981ae7..9e622519a423 100644
--- a/arch/powerpc/mm/book3s64/hash_tlb.c
+++ b/arch/powerpc/mm/book3s64/hash_tlb.c
@@ -30,6 +30,7 @@
#include <trace/events/thp.h>
DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
+EXPORT_SYMBOL_IF_KUNIT(ppc64_tlb_batch); /* For lazy_mmu_mode KUnit tests */
/*
* A linux PTE was changed and the corresponding hash table entry
@@ -154,6 +155,7 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
flush_hash_range(i, local);
batch->index = 0;
}
+EXPORT_SYMBOL_IF_KUNIT(__flush_tlb_pending); /* For lazy_mmu_mode KUnit tests */
void hash__tlb_flush(struct mmu_gather *tlb)
{
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH] mm: Add basic tests for lazy_mmu - fix for powerpc
2025-12-17 4:14 ` Andrew Morton
2025-12-17 9:26 ` Kevin Brodsky
2025-12-17 16:38 ` [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests Kevin Brodsky
@ 2025-12-17 16:38 ` Kevin Brodsky
2 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-17 16:38 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, Ryan Roberts, Ritesh Harjani, linux-mm,
linuxppc-dev, Kevin Brodsky
Add MODULE_IMPORT_NS() for symbols referenced on powerpc.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
Andrew, please squash this into the last patch in the series
("mm: Add basic tests for lazy_mmu"). Thanks!
---
mm/tests/lazy_mmu_mode_kunit.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/mm/tests/lazy_mmu_mode_kunit.c b/mm/tests/lazy_mmu_mode_kunit.c
index 2720eb995714..1c23456b467e 100644
--- a/mm/tests/lazy_mmu_mode_kunit.c
+++ b/mm/tests/lazy_mmu_mode_kunit.c
@@ -2,6 +2,9 @@
#include <kunit/test.h>
#include <linux/pgtable.h>
+/* For some symbols referenced by arch_{enter,leave}_lazy_mmu_mode on powerpc */
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
+
static void expect_not_active(struct kunit *test)
{
KUNIT_EXPECT_FALSE(test, is_lazy_mmu_mode_active());
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
--
2.51.2
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests
2025-12-17 16:38 ` [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests Kevin Brodsky
@ 2025-12-17 16:45 ` Ritesh Harjani
2025-12-17 17:30 ` Andrew Morton
2025-12-21 23:42 ` kernel test robot
1 sibling, 1 reply; 29+ messages in thread
From: Ritesh Harjani @ 2025-12-17 16:45 UTC (permalink / raw)
To: Kevin Brodsky, Andrew Morton
Cc: linux-kernel, Ryan Roberts, linux-mm, linuxppc-dev, Kevin Brodsky
Kevin Brodsky <kevin.brodsky@arm.com> writes:
> Upcoming KUnit tests will call lazy_mmu_mode_{enable,disable}.
> These tests may be built as a module, and because of inlining this
> means that symbols referenced by arch_{enter,leave}_lazy_mmu_mode
> need to be exported.
>
> Suggested-by: Ryan Roberts <ryan.roberts@arm.com>
> Suggested-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
Hi Kevin,
I guess, this can give following errors:
../arch/powerpc/mm/book3s64/hash_tlb.c:33:1: error: data definition has no type or storage class [-Werror]
33 | EXPORT_SYMBOL_IF_KUNIT(ppc64_tlb_batch); /* For lazy_mmu_mode KUnit tests */
| ^~~~~~~~~~~~~~~~~~~~~~
../arch/powerpc/mm/book3s64/hash_tlb.c:33:1: error: type defaults to ‘int’ in declaration of ‘EXPORT_SYMBOL_IF_KUNIT’ [-Werror=implicit-int]
../arch/powerpc/mm/book3s64/hash_tlb.c:33:1: error: parameter names (without types) in function declaration [-Werror]
../arch/powerpc/mm/book3s64/hash_tlb.c:158:1: error: data definition has no type or storage class [-Werror]
158 | EXPORT_SYMBOL_IF_KUNIT(__flush_tlb_pending); /* For lazy_mmu_mode KUnit tests */
| ^~~~~~~~~~~~~~~~~~~~~~
../arch/powerpc/mm/book3s64/hash_tlb.c:158:1: error: type defaults to ‘int’ in declaration of ‘EXPORT_SYMBOL_IF_KUNIT’ [-Werror=implicit-int]
../arch/powerpc/mm/book3s64/hash_tlb.c:158:1: error: parameter names (without types) in function declaration [-Werror]
AR init/built-in.a
cc1: all warnings being treated as errors
make[6]: *** [../scripts/Makefile.build:287: arch/powerpc/mm/book3s64/hash_tlb.o] Error 1
make[5]: *** [../scripts/Makefile.build:556: arch/powerpc/mm/book3s64] Error 2
IMO, we will need the following header in hash_tlb.c
+#include <kunit/visibility.h>
-ritesh
>
> Andrew, please add this patch just before the last patch in the series
> ("mm: Add basic tests for lazy_mmu"). Thanks!
> ---
> arch/powerpc/mm/book3s64/hash_tlb.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/powerpc/mm/book3s64/hash_tlb.c b/arch/powerpc/mm/book3s64/hash_tlb.c
> index fbdeb8981ae7..9e622519a423 100644
> --- a/arch/powerpc/mm/book3s64/hash_tlb.c
> +++ b/arch/powerpc/mm/book3s64/hash_tlb.c
> @@ -30,6 +30,7 @@
> #include <trace/events/thp.h>
>
> DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
> +EXPORT_SYMBOL_IF_KUNIT(ppc64_tlb_batch); /* For lazy_mmu_mode KUnit tests */
>
> /*
> * A linux PTE was changed and the corresponding hash table entry
> @@ -154,6 +155,7 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
> flush_hash_range(i, local);
> batch->index = 0;
> }
> +EXPORT_SYMBOL_IF_KUNIT(__flush_tlb_pending); /* For lazy_mmu_mode KUnit tests */
>
> void hash__tlb_flush(struct mmu_gather *tlb)
> {
>
> base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
> --
> 2.51.2
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests
2025-12-17 16:45 ` Ritesh Harjani
@ 2025-12-17 17:30 ` Andrew Morton
2025-12-17 17:37 ` Kevin Brodsky
0 siblings, 1 reply; 29+ messages in thread
From: Andrew Morton @ 2025-12-17 17:30 UTC (permalink / raw)
To: Ritesh Harjani
Cc: Kevin Brodsky, linux-kernel, Ryan Roberts, linux-mm, linuxppc-dev
On Wed, 17 Dec 2025 22:15:16 +0530 Ritesh Harjani (IBM) <ritesh.list@gmail.com> wrote:
> ../arch/powerpc/mm/book3s64/hash_tlb.c:158:1: error: type defaults to ‘int’ in declaration of ‘EXPORT_SYMBOL_IF_KUNIT’ [-Werror=implicit-int]
> ../arch/powerpc/mm/book3s64/hash_tlb.c:158:1: error: parameter names (without types) in function declaration [-Werror]
> AR init/built-in.a
> cc1: all warnings being treated as errors
> make[6]: *** [../scripts/Makefile.build:287: arch/powerpc/mm/book3s64/hash_tlb.o] Error 1
> make[5]: *** [../scripts/Makefile.build:556: arch/powerpc/mm/book3s64] Error 2
>
>
> IMO, we will need the following header in hash_tlb.c
>
> +#include <kunit/visibility.h>
Yeah, I already added Ritesh's patch which had this include, so I
think we're all good now.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests
2025-12-17 17:30 ` Andrew Morton
@ 2025-12-17 17:37 ` Kevin Brodsky
0 siblings, 0 replies; 29+ messages in thread
From: Kevin Brodsky @ 2025-12-17 17:37 UTC (permalink / raw)
To: Andrew Morton, Ritesh Harjani (IBM)
Cc: linux-kernel, Ryan Roberts, linux-mm, linuxppc-dev
On 17/12/2025 18:30, Andrew Morton wrote:
> On Wed, 17 Dec 2025 22:15:16 +0530 Ritesh Harjani (IBM) <ritesh.list@gmail.com> wrote:
>
>> ../arch/powerpc/mm/book3s64/hash_tlb.c:158:1: error: type defaults to ‘int’ in declaration of ‘EXPORT_SYMBOL_IF_KUNIT’ [-Werror=implicit-int]
>> ../arch/powerpc/mm/book3s64/hash_tlb.c:158:1: error: parameter names (without types) in function declaration [-Werror]
>> AR init/built-in.a
>> cc1: all warnings being treated as errors
>> make[6]: *** [../scripts/Makefile.build:287: arch/powerpc/mm/book3s64/hash_tlb.o] Error 1
>> make[5]: *** [../scripts/Makefile.build:556: arch/powerpc/mm/book3s64] Error 2
>>
>>
>> IMO, we will need the following header in hash_tlb.c
>>
>> +#include <kunit/visibility.h>
Ha strange it built fine for me without it... Maybe different config
options.
> Yeah, I already added Ritesh's patch which had this include, so I
> think we're all good now.
Great thanks both!
- Kevin
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests
2025-12-17 16:38 ` [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests Kevin Brodsky
2025-12-17 16:45 ` Ritesh Harjani
@ 2025-12-21 23:42 ` kernel test robot
1 sibling, 0 replies; 29+ messages in thread
From: kernel test robot @ 2025-12-21 23:42 UTC (permalink / raw)
To: Kevin Brodsky, Andrew Morton
Cc: oe-kbuild-all, Linux Memory Management List, linux-kernel,
Ryan Roberts, Ritesh Harjani, linuxppc-dev, Kevin Brodsky
Hi Kevin,
kernel test robot noticed the following build warnings:
url: https://github.com/intel-lab-lkp/linux/commits/UPDATE-20251218-003955/Kevin-Brodsky/powerpc-64s-Do-not-re-activate-batched-TLB-flush/20251215-230757
base: the 14th patch of https://lore.kernel.org/r/20251215150323.2218608-15-kevin.brodsky%40arm.com
patch link: https://lore.kernel.org/r/20251217163812.2633648-1-kevin.brodsky%40arm.com
patch subject: [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests
config: powerpc-allmodconfig (https://download.01.org/0day-ci/archive/20251222/202512220735.UL4ukFLo-lkp@intel.com/config)
compiler: powerpc64-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251222/202512220735.UL4ukFLo-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512220735.UL4ukFLo-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> arch/powerpc/mm/book3s64/hash_tlb.c:33:1: warning: data definition has no type or storage class
33 | EXPORT_SYMBOL_IF_KUNIT(ppc64_tlb_batch); /* For lazy_mmu_mode KUnit tests */
| ^~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/mm/book3s64/hash_tlb.c:33:1: error: type defaults to 'int' in declaration of 'EXPORT_SYMBOL_IF_KUNIT' [-Wimplicit-int]
arch/powerpc/mm/book3s64/hash_tlb.c:33:1: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
arch/powerpc/mm/book3s64/hash_tlb.c:158:1: warning: data definition has no type or storage class
158 | EXPORT_SYMBOL_IF_KUNIT(__flush_tlb_pending); /* For lazy_mmu_mode KUnit tests */
| ^~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/mm/book3s64/hash_tlb.c:158:1: error: type defaults to 'int' in declaration of 'EXPORT_SYMBOL_IF_KUNIT' [-Wimplicit-int]
arch/powerpc/mm/book3s64/hash_tlb.c:158:1: error: parameter names (without types) in function declaration [-Wdeclaration-missing-parameter-type]
vim +33 arch/powerpc/mm/book3s64/hash_tlb.c
31
32 DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
> 33 EXPORT_SYMBOL_IF_KUNIT(ppc64_tlb_batch); /* For lazy_mmu_mode KUnit tests */
34
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2025-12-21 23:42 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-15 15:03 [PATCH v6 00/14] Nesting support for lazy MMU mode Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 01/14] powerpc/64s: Do not re-activate batched TLB flush Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 02/14] x86/xen: simplify flush_lazy_mmu() Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 03/14] powerpc/mm: implement arch_flush_lazy_mmu_mode() Kevin Brodsky
2025-12-16 5:14 ` Ritesh Harjani
2025-12-15 15:03 ` [PATCH v6 04/14] sparc/mm: " Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 05/14] mm: clarify lazy_mmu sleeping constraints Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 06/14] mm: introduce CONFIG_ARCH_HAS_LAZY_MMU_MODE Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 07/14] mm: introduce generic lazy_mmu helpers Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 08/14] mm: bail out of lazy_mmu_mode_* in interrupt context Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 09/14] mm: enable lazy_mmu sections to nest Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 10/14] arm64: mm: replace TIF_LAZY_MMU with is_lazy_mmu_mode_active() Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 11/14] powerpc/mm: replace batch->active " Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 12/14] sparc/mm: " Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 13/14] x86/xen: use lazy_mmu_state when context-switching Kevin Brodsky
2025-12-15 15:03 ` [PATCH v6 14/14] mm: Add basic tests for lazy_mmu Kevin Brodsky
2025-12-17 4:14 ` Andrew Morton
2025-12-17 9:26 ` Kevin Brodsky
2025-12-17 10:01 ` Ryan Roberts
2025-12-17 15:37 ` Kevin Brodsky
2025-12-17 15:46 ` Ritesh Harjani
2025-12-17 16:10 ` Kevin Brodsky
2025-12-17 16:38 ` [PATCH] powerpc/mm: export symbols for lazy_mmu_mode KUnit tests Kevin Brodsky
2025-12-17 16:45 ` Ritesh Harjani
2025-12-17 17:30 ` Andrew Morton
2025-12-17 17:37 ` Kevin Brodsky
2025-12-21 23:42 ` kernel test robot
2025-12-17 16:38 ` [PATCH] mm: Add basic tests for lazy_mmu - fix for powerpc Kevin Brodsky
2025-12-15 16:52 ` [PATCH v6 00/14] Nesting support for lazy MMU mode Yeoreum Yun
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).