]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
arm64: enable PREEMPT_LAZY
authorMark Rutland <mark.rutland@arm.com>
Wed, 5 Mar 2025 10:49:25 +0000 (11:49 +0100)
committerWill Deacon <will@kernel.org>
Tue, 29 Apr 2025 12:44:47 +0000 (13:44 +0100)
For an architecture to enable CONFIG_ARCH_HAS_RESCHED_LAZY, two things are
required:
1) Adding a TIF_NEED_RESCHED_LAZY flag definition
2) Checking for TIF_NEED_RESCHED_LAZY in the appropriate locations

2) is handled in a generic manner by CONFIG_GENERIC_ENTRY, which isn't
(yet) implemented for arm64. However, outside of core scheduler code,
TIF_NEED_RESCHED_LAZY only needs to be checked on a kernel exit, meaning:
o return/entry to userspace.
o return/entry to guest.

The return/entry to a guest is all handled by xfer_to_guest_mode_handle_work()
which already does the right thing, so it can be left as-is.

arm64 doesn't use common entry's exit_to_user_mode_prepare(), so update its
return to user path to check for TIF_NEED_RESCHED_LAZY and call into
schedule() accordingly.

Link: https://lore.kernel.org/linux-rt-users/20241216190451.1c61977c@mordecai.tesarici.cz/
Link: https://lore.kernel.org/all/xhsmh4j0fl0p3.mognet@vschneid-thinkpadt14sgen2i.remote.csb/
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
[testdrive, _TIF_WORK_MASK fixlet and changelog.]
Signed-off-by: Mike Galbraith <efault@gmx.de>
[Another round of testing; changelog faff]
Signed-off-by: Valentin Schneider <vschneid@redhat.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lore.kernel.org/r/20250305104925.189198-2-vschneid@redhat.com
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/Kconfig
arch/arm64/include/asm/thread_info.h
arch/arm64/kernel/entry-common.c

index a182295e6f08bfa0f3e6f630dc4adfe797a4d273..84e3094b00ef2445997571307fdf31291272d94c 100644 (file)
@@ -42,6 +42,7 @@ config ARM64
        select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
        select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
        select ARCH_HAS_NONLEAF_PMD_YOUNG if ARM64_HAFT
+       select ARCH_HAS_PREEMPT_LAZY
        select ARCH_HAS_PTDUMP
        select ARCH_HAS_PTE_DEVMAP
        select ARCH_HAS_PTE_SPECIAL
index 1114c1c3300a13105863664b083e1714048f7c86..4443ef2789758e9962f243a9097230b412704372 100644 (file)
@@ -59,11 +59,12 @@ void arch_setup_new_exec(void);
 
 #define TIF_SIGPENDING         0       /* signal pending */
 #define TIF_NEED_RESCHED       1       /* rescheduling necessary */
-#define TIF_NOTIFY_RESUME      2       /* callback before returning to user */
-#define TIF_FOREIGN_FPSTATE    3       /* CPU's FP state is not current's */
-#define TIF_UPROBE             4       /* uprobe breakpoint or singlestep */
-#define TIF_MTE_ASYNC_FAULT    5       /* MTE Asynchronous Tag Check Fault */
-#define TIF_NOTIFY_SIGNAL      6       /* signal notifications exist */
+#define TIF_NEED_RESCHED_LAZY  2       /* Lazy rescheduling needed */
+#define TIF_NOTIFY_RESUME      3       /* callback before returning to user */
+#define TIF_FOREIGN_FPSTATE    4       /* CPU's FP state is not current's */
+#define TIF_UPROBE             5       /* uprobe breakpoint or singlestep */
+#define TIF_MTE_ASYNC_FAULT    6       /* MTE Asynchronous Tag Check Fault */
+#define TIF_NOTIFY_SIGNAL      7       /* signal notifications exist */
 #define TIF_SYSCALL_TRACE      8       /* syscall trace active */
 #define TIF_SYSCALL_AUDIT      9       /* syscall auditing */
 #define TIF_SYSCALL_TRACEPOINT 10      /* syscall tracepoint for ftrace */
@@ -85,6 +86,7 @@ void arch_setup_new_exec(void);
 
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
+#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_FOREIGN_FPSTATE   (1 << TIF_FOREIGN_FPSTATE)
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
@@ -100,10 +102,10 @@ void arch_setup_new_exec(void);
 #define _TIF_NOTIFY_SIGNAL     (1 << TIF_NOTIFY_SIGNAL)
 #define _TIF_TSC_SIGSEGV       (1 << TIF_TSC_SIGSEGV)
 
-#define _TIF_WORK_MASK         (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
+#define _TIF_WORK_MASK         (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY | \
                                 _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \
                                 _TIF_UPROBE | _TIF_MTE_ASYNC_FAULT | \
-                                _TIF_NOTIFY_SIGNAL)
+                                _TIF_NOTIFY_SIGNAL | _TIF_SIGPENDING)
 
 #define _TIF_SYSCALL_WORK      (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
                                 _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
index b260ddc4d3e9ad80ca1f5480c1be96523233a126..7993fab0cab4cabde087812ea06f510f84573339 100644 (file)
@@ -132,7 +132,7 @@ static void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
        do {
                local_irq_enable();
 
-               if (thread_flags & _TIF_NEED_RESCHED)
+               if (thread_flags & (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY))
                        schedule();
 
                if (thread_flags & _TIF_UPROBE)