Re: [patch V6 01/11] rseq: Add fields and constants for time slice extension

From: Mathieu Desnoyers
Date: Wed Jan 07 2026 - 17:35:29 EST


On 2025-12-18 18:21, Thomas Gleixner wrote:
On Tue, Dec 16 2025 at 09:36, Mathieu Desnoyers wrote:
On 2025-12-15 13:24, Thomas Gleixner wrote:
[...]
+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);

Although it is not documented, it appears that a thread can
also use this prctl to disable slice extension.

Obviously. Controls are supposed to be symmetrical.

I agree that the vast majority of prctl are symmetrical, but
there are exceptions, e.g. PR_SET_NO_NEW_PRIVS, PR_SET_SECCOMP.

How is it meant to compose once we have libc trying to use slice
extension internally and the application also using it or wishing to
disable it, unaware that libc is also trying to use it ?

Tons of prctls have the same "issue". What's so special about this?

What is special about this is the fact that we want to allow userspace
to specialize its fast-path code at runtime based on availability of an
rseq feature.

If we allow slice extension to be disabled by the program or any
library within the process, this means that either the program or any
other library cannot assume slice extension availability to stay
invariant after it has been setup. This therefore requires adding
additional feature availability tests on the fast-path. And if this
state is per-thread, this means testing flags within the rseq area
on every use. Even if this is a simple load from an address at
thread pointer + offset, test, and branch, the overhead adds up quickly
for fast-paths.

Moreover, if the prctl enables the feature independently for each
thread (rather than for the whole process), this requires a conditional
state check on every use because it can be enabled or disabled
depending on the thread. This prevents code specialization that would
select the appropriate code at process startup through either ifunc
resolver, code patching or other mean.

[...]

The prctl allows you to query the state, so all parties can make
informed decisions. It's not any different from other mechanisms, which
require coordination between different parts.

I'm fine with having prctl enable the feature (for the whole process)
and query its state.

The part I'm concerned with is the prctl disabling the feature, as
we're losing the availability invariant after setup.


This goes against the design goals of RSEQ features.

These goals are documented where?

We should clarify those design goals somewhere. So far those have
been enforced by me when vetting new features, but that approach
is not good in the long term.

Is Documentation/userspace-api/rseq.rst a good location for this ?


What I've seen so far at least from the implementation is that it aims
to enable the maximum amount of features, aka. overhead, unconditionally
even if nothing uses them, e.g. CID.

I don't mind having things disabled on process startup and then opt-in.
What I care about though is that the enabled state stays invariant across
the entire process after setting this up at program startup.

I agree with you in retrospect that this opt-in approach should have been
taken for CID.

Your vision/goal of RSEQ being useful everywhere simply does not match
the reality.

Again, I don't mind the opt-in approach, only that the state stays invariant
after program startup.

As I pointed out in the previous submission, the benefits of time slice
extensions are limited. In low contention scenarios they result in
measurable regressions, so it's not the magic panacea which solves all
locking/critical section problems at once.

I agree that whatever code we add to an uncontended spinlock fast path
will show up in microbenchmark measurements.


The idea that cobbling random libraries together in the hope that
everything goes well has never worked. That's simply a wet dream and
Java has proven that to the maximum extent decades ago. Nevertheless all
other programming models went down the same yawning abyss and everyone
expects that the kernel is magically solving their problems by adding
more abusable [mis]features.

Systems have to be designed carefully as a whole if you want to achieve
the maximum performance. That's not any different from other targets
like real-time. A real-time enabled kernel does not magically create a
real-time system.
[...]

I think we are talking about two different program/libraries composition
use-cases here.

AFAIU, the aspect you are focused on is whether we should allow users of
slice extension to nest. I agree with you that we should document this
as unsupported, since the goal of slice extension is really for short
spinlock critical sections, and nesting of those goes against that
basic definition.

The concern I am raising here is different. It's about just _using_
slice extension from various entities (program, libraries) within a
process, without any nesting of slice extension requests.

If libc successfully enables slice extension in its startup, the
kernel should guarantee that it stays invariant for the lifetime
of the program so libc can optimize its code accordingly, or use
a fallback, without requiring additional per-thread variable checks
in its fast paths.

Thanks,

Mathieu

--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com