Re: [patch 02/12] rseq: Add fields and constants for time slice extension

Randy Dunlap
2025-09-09T00:04:25Z

Hi Thomas,

On 9/8/25 3:59 PM, Thomas Gleixner wrote:
> Aside of a Kconfig knob add the following items:
>

> ---
> Documentation/userspace-api/index.rst | 1
> Documentation/userspace-api/rseq.rst | 129 ++++++++++++++++++++++++++++++++++
> include/linux/rseq_types.h | 26 ++++++
> include/uapi/linux/rseq.h | 28 +++++++
> init/Kconfig | 12 +++
> kernel/rseq.c | 8 ++
> 6 files changed, 204 insertions(+)
>

> --- /dev/null
> +++ b/Documentation/userspace-api/rseq.rst
> @@ -0,0 +1,129 @@
> +=====================
> +Restartable Sequences
> +=====================
> +
> +Restartable Sequences allow to register a per thread userspace memory area
> +to be used as an ABI between kernel and user-space for three purposes:

userspace or user-space or user space -- be consistent, please.
(above 2 times, and more below)

FWIW, "userspace" overwhelmingly wins in the kernel source tree.
On the $internet it looks like "user space" wins (quick look).

> +
> + * user-space restartable sequences
> +
> + * quick access to read the current CPU number, node ID from user-space
> +
> + * scheduler time slice extensions
> +
> +Restartable sequences (per-cpu atomics)
> +---------------------------------------
> +
> +Restartables sequences allow user-space to perform update operations on
> +per-cpu data without requiring heavy-weight atomic operations. The actual
just heavyweight

> +ABI is unfortunately only available in the code and selftests.
> +
> +Quick access to CPU number, node ID
> +-----------------------------------
> +
> +Allows to implement per CPU data efficiently. Documentation is in code and
> +selftests. :(
> +
> +Scheduler time slice extensions
> +-------------------------------
> +
> +This allows a thread to request a time slice extension when it enters a
> +critical section to avoid contention on a resource when the thread is
> +scheduled out inside of the critical section.
> +
> +The prerequisites for this functionality are:
> +
> + * Enabled in Kconfig
> +
> + * Enabled at boot time (default is enabled)
> +
> + * A rseq user space pointer has been registered for the thread

^^^^^^^^^^

> +
> +The thread has to enable the functionality via prctl(2)::
> +
> + prctl(PR_RSEQ_SLICE_EXTENSION, PR_RSEQ_SLICE_EXTENSION_SET,
> + PR_RSEQ_SLICE_EXT_ENABLE, 0, 0);
> +
> +prctl() returns 0 on success and otherwise with the following error codes:
> +
> +========= ==============================================================
> +Errorcode Meaning
> +========= ==============================================================
> +EINVAL Functionality not available or invalid function arguments.
> + Note: arg4 and arg5 must be zero
> +ENOTSUPP Functionality was disabled on the kernel command line
> +ENXIO Available, but no rseq user struct registered
> +========= ==============================================================
> +
> +The state can be also queried via prctl(2)::
> +
> + prctl(PR_RSEQ_SLICE_EXTENSION, PR_RSEQ_SLICE_EXTENSION_GET, 0, 0, 0);
> +
> +prctl() returns ``PR_RSEQ_SLICE_EXT_ENABLE`` when it is enabled or 0 if
> +disabled. Otherwise it returns with the following error codes:
> +
> +========= ==============================================================
> +Errorcode Meaning
> +========= ==============================================================
> +EINVAL Functionality not available or invalid function arguments.
> + Note: arg3 and arg4 and arg5 must be zero
> +========= ==============================================================
> +
> +The availability and status is also exposed via the rseq ABI struct flags
> +field via the ``RSEQ_CS_FLAG_SLICE_EXT_AVAILABLE_BIT`` and the
> +``RSEQ_CS_FLAG_SLICE_EXT_ENABLED_BIT``. These bits are read only for user

read-only for

> +space and only for informational purposes.

userspace ?

> +
> +If the mechanism was enabled via prctl(), the thread can request a time
> +slice extension by setting the ``RSEQ_SLICE_EXT_REQUEST_BIT`` in the struct
> +rseq slice_ctrl field. If the thread is interrupted and the interrupt
> +results in a reschedule request in the kernel, then the kernel can grant a
> +time slice extension and return to user space instead of scheduling

^^^^^^^^^^

> +out.
> +
> +The kernel indicates the grant by clearing ``RSEQ_SLICE_EXT_REQUEST_BIT``
> +and setting ``RSEQ_SLICE_EXT_GRANTED_BIT`` in the rseq::slice_ctrl
> +field. If there is a reschedule of the thread after granting the extension,
> +the kernel clears the granted bit to indicate that to user space.

?

> +
> +If the request bit is still set when the leaving the critical section, user
> +space can clear it and continue.

?

> +
> +If the granted bit is set, then user space has to invoke rseq_slice_yield()

?

> +when leaving the critical section to relinquish the CPU. The kernel
> +enforces this by arming a timer to prevent misbehaving user space from

OK, I think that you like "user space". :)

> +abusing this mechanism.
> +
> +If both the request bit and the granted bit are false when leaving the
> +critical section, then this indicates that a grant was revoked and no
> +further action is required by user space.
> +
> +The required code flow is as follows::
> +
> + rseq->slice_ctrl = REQUEST;
> + critical_section();
> + if (!local_test_and_clear_bit(REQUEST, &rseq->slice_ctrl)) {
> + if (rseq->slice_ctrl & GRANTED)
> + rseq_slice_yield();
> + }
> +
> +local_test_and_clear_bit() has to be local CPU atomic to prevent the
> +obvious RMW race versus an interrupt. On X86 this can be achieved with BTRL
> +without LOCK prefix. On architectures, which do not provide lightweight CPU

no comma ^

> +local atomics this needs to be implemented with regular atomic operations.
> +
> +Setting REQUEST has no atomicity requirements as there is no concurrency
> +vs. the GRANTED bit.
> +
> +Checking the GRANTED has no atomicity requirements as there is obviously a
> +race which cannot be avoided at all::
> +
> + if (rseq->slice_ctrl & GRANTED)
> + -> Interrupt results in schedule and grant revocation
> + rseq_slice_yield();
> +
> +So there is no point in pretending that this might be solved by an atomic
> +operation.
> +
> +The kernel enforces flag consistency and terminates the thread with SIGSEGV
> +if it detects a violation.

> --- a/include/uapi/linux/rseq.h
> +++ b/include/uapi/linux/rseq.h
> @@ -23,9 +23,15 @@ enum rseq_flags {
> };
>
> enum rseq_cs_flags_bit {
> + /* Historical and unsupported bits */
> RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0,
> RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1,
> RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2,
> + /* (3) Intentional gap to put new bits into a seperate byte */

separate
("There is a rat in separate." -- old clue)
'arat'

> +
> + /* User read only feature flags */
> + RSEQ_CS_FLAG_SLICE_EXT_AVAILABLE_BIT = 4,
> + RSEQ_CS_FLAG_SLICE_EXT_ENABLED_BIT = 5,
> };
>
> enum rseq_cs_flags {

> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1908,6 +1908,18 @@ config RSEQ_DEBUG_DEFAULT_ENABLE
>
> If unsure, say N.
>
> +config RSEQ_SLICE_EXTENSION
> + bool "Enable rseq based time slice extension mechanism"

rseq-based

> + depends on RSEQ && HIGH_RES_TIMERS && GENERIC_ENTRY && HAVE_GENERIC_TIF_BITS
> + help
> + Allows userspace to request a limited time slice extension when

Use tab + 2 spaces above instead of N spaces.

> + returning from an interrupt to user space via the RSEQ shared
> + data ABI. If granted, that allows to complete a critical section,
> + so that other threads are not stuck on a conflicted resource,
> + while the task is scheduled out.
--
~Randy