diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2025-12-15 17:52:15 +0100 |
|---|---|---|
| committer | Peter Zijlstra <peterz@infradead.org> | 2026-01-22 11:11:17 +0100 |
| commit | 99d2592023e5d0a31f5f5a83c694df48239a1e6c (patch) | |
| tree | f58a294e6f752c04fdf00f9d6c7360380722d4d4 /kernel | |
| parent | 28621ec2d46c6adf7d33a6facbd83e2fa566bd34 (diff) | |
rseq: Implement sys_rseq_slice_yield()
Provide a new syscall which has the only purpose to yield the CPU after the
kernel granted a time slice extension.
sched_yield() is not suitable for that because it unconditionally
schedules, but the end of the time slice extension is not required to
schedule when the task was already preempted. This also allows to have a
strict check for termination to catch user space invoking random syscalls
including sched_yield() from a time slice extension region.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Link: https://patch.msgid.link/20251215155708.929634896@linutronix.de
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/rseq.c | 21 | ||||
| -rw-r--r-- | kernel/sys_ni.c | 1 |
2 files changed, 22 insertions, 0 deletions
diff --git a/kernel/rseq.c b/kernel/rseq.c index 09848bb14ec2..d8e1992edffa 100644 --- a/kernel/rseq.c +++ b/kernel/rseq.c @@ -553,6 +553,27 @@ die: return -EFAULT; } +/** + * sys_rseq_slice_yield - yield the current processor side effect free if a + * task granted with a time slice extension is done with + * the critical work before being forced out. + * + * Return: 1 if the task successfully yielded the CPU within the granted slice. + * 0 if the slice extension was either never granted or was revoked by + * going over the granted extension, using a syscall other than this one + * or being scheduled out earlier due to a subsequent interrupt. + * + * The syscall does not schedule because the syscall entry work immediately + * relinquishes the CPU and schedules if required. + */ +SYSCALL_DEFINE0(rseq_slice_yield) +{ + int yielded = !!current->rseq.slice.yielded; + + current->rseq.slice.yielded = 0; + return yielded; +} + static int __init rseq_slice_cmdline(char *str) { bool on; diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index bf5d05c635ff..add3032da16f 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -390,6 +390,7 @@ COND_SYSCALL(setuid16); /* restartable sequence */ COND_SYSCALL(rseq); +COND_SYSCALL(rseq_slice_yield); COND_SYSCALL(uretprobe); COND_SYSCALL(uprobe); |
