Re: [PATCH 1/1] arm64: enable PREEMPT_LAZY

From: Mark Rutland
Date: Wed Mar 05 2025 - 07:15:56 EST


On Wed, Mar 05, 2025 at 11:49:25AM +0100, Valentin Schneider wrote:
> From: Mark Rutland <mark.rutland@xxxxxxx>
>
> 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@xxxxxxxxxxxxxxxxxxxx/
> Link: https://lore.kernel.org/all/xhsmh4j0fl0p3.mognet@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/
> Signed-off-by: Mark Rutland <mark.rutland@xxxxxxx>
> [testdrive, _TIF_WORK_MASK fixlet and changelog.]
> Signed-off-by: Mike Galbraith <efault@xxxxxx>
> [Another round of testing; changelog faff]
> Signed-off-by: Valentin Schneider <vschneid@xxxxxxxxxx>
> ---
> 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(-)

Catalin, Will, given this is small and self-contained, I reckon it makes
sense to pick this up ahead of Jinjie's series to move arm64 over to the
generic entry library (which is on my queue of things to review). Even
if we pick up both, it'll be easier to bisect and debug issues caused by
this patch alone.

The fixes/cleanups from Mike and Valentin look right to me, so FWIW:

Acked-by: Mark Rutland <mark.rutland@xxxxxxx>

Mark.

> 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)
> --
> 2.43.0
>