Re: [patch 00/12] rseq: Implement time slice extension mechanism
From: Mathieu Desnoyers
Date: Fri Sep 12 2025 - 08:33:50 EST
On 2025-09-11 16:18, Thomas Gleixner wrote:
On Thu, Sep 11 2025 at 11:27, Mathieu Desnoyers wrote:[...]
On 2025-09-08 18:59, Thomas Gleixner wrote:
Does it "have" to ? What is the consequence of misbehaving ?
It receives SIGSEGV because that means that it did not follow the rules
and stuck an arbitrary syscall into the critical section.
Not following the rules could also be done by just looping for a long
time in userspace within or after the critical section, in which case
the timer should catch it.
I wonder if we could achieve this without the cpu-local atomic, and
just rely on simple relaxed-atomic or volatile loads/stores and compiler
barriers in userspace. Let's say we have:
union {
u16 slice_ctrl;
struct {
u8 rseq->slice_request;
u8 rseq->slice_grant;
Interesting way to define a struct member :)
This goes with the usual warning "this code has never even been
remotely close to a compiler, so handle with care" ;-)
};
};
With userspace doing:
rseq->slice_request = true; /* WRITE_ONCE() */
barrier();
critical_section();
barrier();
rseq->slice_request = false; /* WRITE_ONCE() */
if (rseq->slice_grant) /* READ_ONCE() */
rseq_slice_yield();
That should work as it's strictly CPU local. Good point, now that you
said it it's obvious :)
Let me rework it accordingly.
I have two questions wrt ABI here:
1) Do we expect the slice requests to be done from C and higher level
languages or only from assembly ?
2) Slice requests are a good fit for locking. Locking typically
has nesting ability.
We should consider making the slice request ABI a 8-bit
or 16-bit nesting counter to allow nesting of its users.
3) Slice requests are also a good fit for rseq critical sections.
Of course someone could explicitly increment/decrement the
slice request counter before/after the rseq critical sections, but
I think we could do better there and integrate this directly within
the struct rseq_cs as a new critical section flag. Basically, a
critical section with this new RSEQ_CS_SLICE_REQUEST flag (or
better name) set within its descriptor flags would behave as if
the slice request counter is non-zero when preempted without
requiring any extra instruction on the fast path. The only
added overhead would be a check of the rseq->slice_grant flag
when exiting the critical section to conditionally issue
rseq_slice_yield().
This point (3) is an optimization that could come as a future step
if the overhead of incrementing the slice_request proves to be a
bottleneck for rseq critical sections.
In the kernel interrupt return path, if the kernel observes
"rseq->slice_request" set and "rseq->slice_grant" cleared,
it grants the extension and sets "rseq->slice_grant".
They can't be both set. If they are then user space fiddled with the
bits.
Ah, yes, that's true if the kernel clears the slice_request when setting
the slice_grant.
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com