Re: [patch 00/12] rseq: Implement time slice extension mechanism

Mathieu Desnoyers
2025-09-12T12:33:50Z

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.