Restartable Sequences. What are they?

After scouring the XNU kernel source code, I came across restartable ranges [1]. They seem to be a task-level version of the the part of Linux's restartable sequences [2] for user requested synchronization [3] (akin to MEMBARRIER_CMD_RSEQ).

Because of their differences, I would like to know more about how they work and what they are used for.

From what I have gathered [4], they seem to be closer to RCU [5] that waits for eviction (as opposed to completion). But the fact that they are barely mentioned anywhere (see [4]) in the XNU source code

I'd be really happy if you can point me to more information about them and how they compare to rseq (or rcu). What are the XNU devs planning on doing with them?


[1] osfmk/kern/restartable.c: https://github.com/apple-oss-distributions/xnu/blob/f6217f8/osfmk/kern/restartable.c

[2] https://criu.org/Restartable_Sequences

[3] as opposed to (what I think is what makes rseq really cool) automatic eviction on preemption/CPU migration

[4] there seems to be very little information online (including this forum) and the only places inside the XNU kernel source trees that aren't tests are in osfmk/kern/{thread,thread,sched_prim}.{c,h}, which doesn't really give much more information.

[5] Read-Copy-Update: https://www.kernel.org/doc/html/latest/RCU/whatisRCU.html

Answered by DTS Engineer in 906939022

This is definitely a ‘just because you can doesn’t mean you should’ moment (-:

What are the XNU devs planning on doing with them?

To be clear, we can’t talk about The Future™ here on the forums. See tip 3 in Quinn’s Top Ten DevForums Tips.

However, you can see this feature already being used by the Objective-C runtime.

Which brings me back to my original point. While this is technically API, you’d want to think very carefully before using it in a product that you ship to a wide range of end users. The Objective-C runtime has the advantage that it’s built in to the system, so if the system changes in a way that breaks this API it can adapt. In contrast, any third-party products in the same situation would require an urgent, and potentially very difficult, update.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

This is definitely a ‘just because you can doesn’t mean you should’ moment (-:

What are the XNU devs planning on doing with them?

To be clear, we can’t talk about The Future™ here on the forums. See tip 3 in Quinn’s Top Ten DevForums Tips.

However, you can see this feature already being used by the Objective-C runtime.

Which brings me back to my original point. While this is technically API, you’d want to think very carefully before using it in a product that you ship to a wide range of end users. The Objective-C runtime has the advantage that it’s built in to the system, so if the system changes in a way that breaks this API it can adapt. In contrast, any third-party products in the same situation would require an urgent, and potentially very difficult, update.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for the answer! Unfortunately, the "doesn't mean you should" part did not survive my selective reading (more questions at the end).

It turns out that the fact that they are being used by the Objective-C runtime makes them harder to work with on release kernels because they may only be registered once [1].

Luckily, there is a way to get around that restriction by symbol-interposing [2, 3] task_restartable_ranges_register. I have built a little demo/writeup on how one can try it out on release kernels at [4].

It appears as though macOS 26's SDK only registered five such ranges in libobjc, which jumped to thirty-nine in macOS 27. At this rate, we might not have enough spots for the user as there seems to be a limit of 64 registered ranges [5].

  1. Are there plans to remove the "register once only" limitation or to increase the max number of ranges?
  2. Do you see automatic redirection on preemption (similar to linux's rseq) coming to restartable ranges? I would imagine one of the task_restartable_ranges_t.flags bits could opt a range in to this behaviour such that existing ranges used by the scheduler don't completely break.
  3. The current implementation seems to check that the program counter is strictly higher than the start symbol [6]. I went through this in my head many times and it seemed reasonable (because the PC is the next instruction), but in my testing [4], it meant having to add a nop the start of my simple looping range
.text
.globl _myrange_start, _myrange_end
.globl _myrange_recovery
_myrange_start:
    nop
loop:
    b loop
_myrange_end:
_myrange_recovery:
    ret

Why could this be?


[1] https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/kern/restartable.c#L562

[2] dyld-interposing.h: https://github.com/apple-oss-distributions/dyld/blob/dyld-1378/include/mach-o/dyld-interposing.h

[3] great writeup on symbol interposing: https://github.com/DerekSelander/symbol-interposing

[4] full writeup: https://github.com/kimhanm/restartable-ranges-writeup

[5] https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/kern/restartable.c#L75

[6] https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/kern/restartable.c#L203

I can’t help you here. Questions 1 and 2 are about The Future™, and that’s not something we can discuss here on the forums. See tip 3 in Quinn’s Top Ten DevForums Tips.

Question 3 is technically in scope but it’s not something I care to wade in on. My focus here on the forums is on helping developers create products for Apple platforms, and I can’t see any way to use these APIs in such a product, that is, with any hope of long-term compatibility.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"