[REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
Dmitry Vyukov
dvyukov at google.com
Thu Apr 23 05:58:48 PDT 2026
On Thu, 23 Apr 2026 at 14:53, Mathieu Desnoyers
<mathieu.desnoyers at efficios.com> wrote:
>
> 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.
Yes, this is the scenario I had in mind.
> 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