Commit c8597e2d authored by Mark Rutland's avatar Mark Rutland Committed by Will Deacon
Browse files

arm64: enable PREEMPT_LAZY

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: default avatarMark Rutland <mark.rutland@arm.com>
[testdrive, _TIF_WORK_MASK fixlet and changelog.]
Signed-off-by: default avatarMike Galbraith <efault@gmx.de>
[Another round of testing; changelog faff]
Signed-off-by: default avatarValentin Schneider <vschneid@redhat.com>
Reviewed-by: default avatarThomas Gleixner <tglx@linutronix.de>
Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
Reviewed-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lore.kernel.org/r/20250305104925.189198-2-vschneid@redhat.com


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent 0af2f6be
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+9 −7
Original line number Diff line number Diff line
@@ -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 | \
+1 −1
Original line number Diff line number Diff line
@@ -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)