Re: [PATCH] powerpc/syscall: Avoid atomic test_and_clear_thread_flag on fast path
flat view
From: "Christophe Leroy (CS GROUP)" <chleroy@kernel.org>
Date: 2026-09-29 12:43:47
Also in:
lkml
Le 29/09/2026 à 11:50, Shrikanth Hegde a écrit :
On 9/29/26 12:47 PM, Mukesh Kumar Chaurasiya (IBM) wrote:quoted
In system_call_exception(), test_and_clear_thread_flag(TIF_SYSCALL_RET) performs an atomic bit test-and-clear operation on every system call entry. This introduces an unnecessary performance regression on the syscall fast path.Do you have numbers?quoted
Combine the TIF_SYSCALL_RET check with the unlikely error condition from syscall_enter_from_user_mode_randomize_stack() using non-atomic test_thread_flag(). If the flag is set or entry failed, only then clear the flag via clear_thread_flag() and return the error value.It probably needs a fixes tag.
It is not a bug, unless we can figure out a quantified regression.
quoted
Signed-off-by: Mukesh Kumar Chaurasiya (IBM) <redacted> --- arch/powerpc/kernel/syscall.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)diff --git a/arch/powerpc/kernel/syscall.c b/arch/powerpc/kernel/ syscall.c index fbefe1927b10..8529827d697f 100644 --- a/arch/powerpc/kernel/syscall.c +++ b/arch/powerpc/kernel/syscall.c@@ -18,14 +18,12 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0)long ret; syscall_fn f; - if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0))) { + if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0) || + test_thread_flag(TIF_SYSCALL_RET))) { clear_thread_flag(TIF_SYSCALL_RET); return syscall_get_error(current, regs); } - if (unlikely(test_and_clear_thread_flag(TIF_SYSCALL_RET)))I am bit surprised that test_and_clear_bit does atomic operations even when bit is not set.
It does (on ppc64 smp) sync 1: ldarx andc stdcx. bne 1b sync It is optimised to clear a bit that is set. When the bit is already unset you still get the full sequence allthough it does nothing.
quoted
- return syscall_get_error(current, regs); - if (unlikely(r0 >= NR_syscalls)) { if (unlikely(trap_is_unsupported_scv(regs))) { /* Unsupported scv vector */