[REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
Mathieu Desnoyers
mathieu.desnoyers at efficios.com
Thu Apr 23 05:53:13 PDT 2026
On 2026-04-23 08:36, Dmitry Vyukov wrote:
> On Thu, 23 Apr 2026 at 14:29, Mathieu Desnoyers
> <mathieu.desnoyers at efficios.com> wrote:
>>
>> On 2026-04-23 01:53, Dmitry Vyukov wrote:
>> [...]
>>> +linux-man
>>>
>>> This part of the rseq man page needs to be fixed as well I think. The
>>> kernel no longer reliably provides clearing of rseq_cs on preemption,
>>> right?
>>>
>>> https://git.kernel.org/pub/scm/libs/librseq/librseq.git/tree/doc/man/rseq.2#n241
>>
>> I'm maintaining this manual page in librseq.
>>
>>>
>>> "and set to NULL by the kernel when it restarts an assembly
>>> instruction sequence block,
>>> as well as when the kernel detects that it is preempting or delivering
>>> a signal outside of the range targeted by the rseq_cs."
>>
>> I think you got two things confused here.
>>
>> 1) There is currently a bug on arm64 where it fails to honor the
>> rseq ABI contract wrt critical section abort. AFAIU there is a
>> fix proposed for this.
>>
>> 2) Thomas relaxed the implementation of cpu_id_start field updates
>> so it only stores to the rseq area when the current cpu actually
>> changes (migration).
>>
>> So AFAIU the statement in the man page is still fine. It's just arm64
>> that needs fixing.
>
>
> My understanding was that due to the ev->user_irq check here:
>
> +static __always_inline void rseq_sched_switch_event(struct task_struct *t)
> ...
> + bool raise = (ev->user_irq | ev->ids_changed) & ev->has_rseq;
> +
> + if (raise) {
> + ev->sched_switch = true;
> + rseq_raise_notify_resume(t);
> + }
>
> There won't be any rseq-related processing for threads preempted in
> syscalls, which means that rseq_cs won't be NULLed for threads
> preempted inside of syscalls.
Let's see if I understand your concern correctly. Scenario:
A thread is within a rseq critical section. It exits the critical
section without clearing the rseq_cs pointer, expecting the kernel
to lazily clear the rseq_cs pointer eventually when it detects that
it's not nested on top of the userspace critical section anymore.
It then calls a system call _outside_ of the rseq critical section,
but with rseq_cs pointer set. Based on the rseq man page wording,
it would then expect the preemption within the system call to guarantee
clearing that that pointer.
Here is the relevant comment block in the man page:
Updated by user-space, which sets the address of the cur‐
rently active rseq_cs at the beginning of assembly instruc‐
tion sequence block, and set to NULL by the kernel when it
restarts an assembly instruction sequence block, as well as
>>>>>>>>>
when the kernel detects that it is preempting or delivering
a signal outside of the range targeted by the rseq_cs.
>>>>>>>>>
^^^ this
The whole point about lazy-clearing of rseq_cs is that it _may_ happen when
the kernel preempts or delivers a signal (or at any point really), but it's
just an optimization.
Updating the manual page with this wording would match the intent:
Updated by user-space, which sets the address of the cur‐
rently active rseq_cs at the beginning of assembly instruc‐
tion sequence block, and set to NULL by the kernel when it
restarts an assembly instruction sequence block. May be set
to NULL by the kernel when it detects that the current
instruction pointer is outside of the range targeted by
the rseq_cs.
Also needs to be set to NULL by user-space before reclaim‐
ing memory that contains the targeted struct rseq_cs.
Thoughts ?
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com
More information about the linux-arm-kernel
mailing list