Message ID | 20250305104925.189198-2-vschneid@redhat.com |
---|---|
State | New |
Headers | show |
Series | arm64: enable PREEMPT_LAZY | expand |
On Wed, Mar 05, 2025 at 11:49:25AM +0100, Valentin Schneider wrote: > From: Mark Rutland <mark.rutland@arm.com> > > 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> > Acked-by: Mark Rutland <mark.rutland@arm.com> > Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Nice! This gets rid of the .config complaints that you otherwise get when running the rcutorture TREE07 scenario on arm64: Tested-by: Paul E. McKenney <paulmck@kernel.org> > --- > arch/arm64/Kconfig | 1 + > arch/arm64/include/asm/thread_info.h | 16 +++++++++------- > arch/arm64/kernel/entry-common.c | 2 +- > 3 files changed, 11 insertions(+), 8 deletions(-) > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig > index fcdd0ed3eca89..7789d7fb6f191 100644 > --- a/arch/arm64/Kconfig > +++ b/arch/arm64/Kconfig > @@ -41,6 +41,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_PTE_DEVMAP > select ARCH_HAS_PTE_SPECIAL > select ARCH_HAS_HW_PTE_YOUNG > diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h > index 1114c1c3300a1..4443ef2789758 100644 > --- a/arch/arm64/include/asm/thread_info.h > +++ b/arch/arm64/include/asm/thread_info.h > @@ -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 | \ > diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c > index b260ddc4d3e9a..7993fab0cab4c 100644 > --- a/arch/arm64/kernel/entry-common.c > +++ b/arch/arm64/kernel/entry-common.c > @@ -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)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index fcdd0ed3eca89..7789d7fb6f191 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -41,6 +41,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_PTE_DEVMAP select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_HW_PTE_YOUNG diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index 1114c1c3300a1..4443ef2789758 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -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 | \ diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c index b260ddc4d3e9a..7993fab0cab4c 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -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)