LWN: Comments on "Extending restartable sequences with virtual CPU IDs" https://lwn.net/Articles/885818/ This is a special feed containing comments posted to the individual LWN article titled "Extending restartable sequences with virtual CPU IDs". en-us Wed, 08 Oct 2025 14:04:02 +0000 Wed, 08 Oct 2025 14:04:02 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886634/ https://lwn.net/Articles/886634/ Paf <div class="FormattedComment"> Sure, you can do this with flags - sometimes you end up with a flag that basically says “new version”, but it can be done.<br> </div> Thu, 03 Mar 2022 05:02:40 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886633/ https://lwn.net/Articles/886633/ Paf <div class="FormattedComment"> Ah, thank you for that clarification - that’s quite an extra ball of complexity. Interesting :o<br> </div> Thu, 03 Mar 2022 05:01:03 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886581/ https://lwn.net/Articles/886581/ compudj <div class="FormattedComment"> struct rseq is quite different from the usual system call input/output parameters.<br> <p> struct rseq is meant to: have its fields populated/read by both the kernel and user-space, be allocated by a single &quot;owner&quot; library (e.g. glibc), and be used by the application executable as well as by various shared objects.<br> <p> So it&#x27;s not as simple as having the kernel support various versions, because all users of rseq within a process (main executable and shared libraries) need to agree on its size and feature set, because there is only a single struct rseq per thread.<br> <p> Therefore, the solution proposed in the patch set expose the &quot;feature size&quot; supported by the kernel through auxiliary vectors, which allows glibc to allocate enough memory in the per-thread area, and register that to the kernel through sys_rseq. This way, all rseq users within the process can agree on the size of the supported rseq feature set by looking at both glibc&#x27;s __rseq_size and the auxiliary vector rseq feature size.<br> <p> If many struct rseq per thread were a possibility, things would be very much different and then version numbering would be possible, but it&#x27;s been decided otherwise for the sake of keeping the kernel implementation simple and time-bounded.<br> <p> So independently of the preference for version vs size-based extensibility, a version-based extensibility scheme for struct rseq simply won&#x27;t work, because all user-space binaries linked into a process need to agree on the layout.<br> </div> Wed, 02 Mar 2022 15:59:35 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886537/ https://lwn.net/Articles/886537/ smurf <div class="FormattedComment"> You could just set a flag bit. Or add a flag field if there isn&#x27;t one already.<br> <p> </div> Wed, 02 Mar 2022 12:07:34 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886536/ https://lwn.net/Articles/886536/ farnz <p>Same layout but different semantics can be covered by a flags field (with the kernel rejecting requests where the flags are unknown); this means that the same fields can be interpreted differently by different kernel versions, depending on which flags you set. Wed, 02 Mar 2022 11:37:12 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886519/ https://lwn.net/Articles/886519/ Paf <div class="FormattedComment"> By the way, this is (for my money) exactly the point of a version number - backwards compatibility by supporting multiple versions inside the API provider.<br> </div> Wed, 02 Mar 2022 02:21:50 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886518/ https://lwn.net/Articles/886518/ Paf <div class="FormattedComment"> Well, you’ve decided it’s not struct rseq anymore. That’s just something you’ve decided as a definitional line in the sand - it could just as easily be struct rseq v2, with the same layout but different semantics because you decided the earlier semantics were bad.<br> <p> To the second part: well, yes - you’d have to carry support for multiple versions in the kernel. That’s all it means. Other projects do this all time.<br> <p> The opposition to this is just a matter of preferring a new syscall with almost identical semantics or an extra field which changes semantics - which is what would happen if a major deficiency in the semantics were found - to an explicit versioning scheme. And that’s …. It’s a valid preference, though it’s definitely not mine.<br> <p> I’m not asking you to fight this fight in the kernel, the choice has been made by others, but I do know which side I fall on.<br> </div> Wed, 02 Mar 2022 02:20:47 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886512/ https://lwn.net/Articles/886512/ calumapplepie <div class="FormattedComment"> <font class="QuotedText">&gt; The memory allocators (glibc, tcmalloc) will be some of the first heavy users, so I expect we will end up in a situation where having the VCPU_DOMAIN feature enabled will actually bring performance benefits to the overall system (including user-space) due to improved memory allocation/access locality.</font><br> <p> It&#x27;d be very important how they use VCPU_DOMAIN. If they&#x27;re indexing into an array of pointers, it wouldn&#x27;t make a difference for cache locality on a few-core system: 8 cores * 8 bytes/pointer is 64 bytes, conveniently close to where I drew my arbitrary line. Of course, that&#x27;s assuming they align these arrays to cache lines, but I think that&#x27;s a perfectly reasonable optimization to expect.<br> <p> Of course, if they&#x27;re using them in any other way, than the cache optimizations are up for grabs. <br> <p> <font class="QuotedText">&gt; I would like to see numbers here</font><br> <p> Sadly, like any annoying internet commentator, I am not tooled up to provide any numbers to back up my wild assertions.<br> <p> <font class="QuotedText">&gt; I expect that having the memory allocator pools spread over fewer vcpu ids (compared to number of possible cpus) will provide significant gains on workloads that have few concurrently running threads that migrate between cores.</font><br> <p> That is an excellent argument that I did not think into: how migration between cores would interact with the cache locality. I think there are some problems with assuming that locality would naturally increase using VCPU versus a standard ID, however. <br> <p> Firstly, I believe (though I could be very wrong) that the scheduler will try to preferentially place a process on the same core repeatedly, so it can benefit from L1 caches. If that is the case, VCPU makes fairly little difference in practice: the indexed structure will be repeatedly accessed at the same location, holding the same cache lines hot.<br> <p> Also, because the differences only matter when tasks migrate cores, by necessity the L1 and (possibly) the L2 caches won&#x27;t matter. The difference made by caches is thus limited sharply.<br> <p> <font class="QuotedText">&gt; You are also presuming that virtual CPU IDs bring a 2% performance degradation. Is that number made up or did you benchmark the patch series discussed in the article ?</font><br> <p> Completely and utterly made up. These are the idle theories of a procrastinating college students.<br> </div> Wed, 02 Mar 2022 02:20:25 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886498/ https://lwn.net/Articles/886498/ compudj <div class="FormattedComment"> If an existing struct rseq field needs to change semantic/behavior, then it is not struct rseq anymore, and it would be named something else, and possibly registered through a new system call or with specific flags set when calling sys_rseq. The extensibility scheme for struct rseq is &quot;append only&quot; on purpose, so user-space applications can rely on having the exposed structure content unchanged in future kernels.<br> <p> An explicit version number that would be expected to change the semantic of existing struct rseq fields whenever it is bumped would not be practical: an application supporting the current version number could not hope to support newer versions until it is recompiled, which is a no-go in terms of backward compatibility of kernel ABIs exposed to user-space.<br> </div> Tue, 01 Mar 2022 19:27:04 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886488/ https://lwn.net/Articles/886488/ Paf <div class="FormattedComment"> The - huge - disadvantage is that any version changes must be size modifying. What if there’s a bug or a desire to change the behavior of an existing field? Well, we can’t handle it with versioning unless we want to blow out the size.<br> <p> Full stop, end of story. Sadness and clever workarounds ensue.<br> </div> Tue, 01 Mar 2022 15:38:47 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886444/ https://lwn.net/Articles/886444/ farnz <p>The length of the struct <em>is</em> a version number; each "API level" has a fixed size struct, where you only access elements that you're supposed to given the known struct size. <p>If user space passes in a struct whose size isn't one of the known values, whether it be very large and invalid, or just from a newer kernel version, the kernel rejects it, same as it would if the version number is wrong. <p>The extensions are ordered by presence in the kernel; if two extensions want extra data, then that's two separate struct fields, and the struct as a whole grows (it's a struct, not a union). The flags tell the kernel which fields are valid. <p>The advantage of size as opposed to version number is that C makes it easy to get right. I call the syscall with a pointer to the struct, and sizeof(user-space version of struct), and the compiler will assist me in getting it right (failing if I try to fill in fields I don't have, not letting me give a version number that's larger than the struct). All I have to do is ensure that the compiler can see the right definition for the struct, and I'm golden. Tue, 01 Mar 2022 13:24:55 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886442/ https://lwn.net/Articles/886442/ xecycle <div class="FormattedComment"> Oh, we are &quot;extending&quot; it to fit in a smaller space :)<br> </div> Tue, 01 Mar 2022 11:02:57 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886439/ https://lwn.net/Articles/886439/ Cyberax <div class="FormattedComment"> <font class="QuotedText">&gt; What happens if a future extension wants two versions of the call, each with some extra data that happens to be the same size?</font><br> <p> - Doctor, it hurts when I do that!<br> - Then don&#x27;t do it.<br> <p> Gradual steps, gradual steps.<br> </div> Tue, 01 Mar 2022 10:18:16 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886436/ https://lwn.net/Articles/886436/ taladar <div class="FormattedComment"> Is that just me or does that whole business of identifying the version of the struct by its size smell quite a bit?<br> <p> Why not include a version number in the struct?<br> <p> What happens if user-space passes in an invalid size (e.g. very large)?<br> <p> What happens if a future extension wants two versions of the call, each with some extra data that happens to be the same size?<br> <p> This just seems like a way to implement this that is broken by design.<br> </div> Tue, 01 Mar 2022 08:25:38 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886430/ https://lwn.net/Articles/886430/ compudj <div class="FormattedComment"> I agree with your statement about not multiplying the number of semi-useless config options, and this is indeed one of my objectives. So currently CONFIG_VCPU_DOMAIN is only enabled if CONFIG_RSEQ and CONFIG_SMP are enabled, but it is not exposed as an explicit Kconfig option. This means building a kernel without this feature is as simple as configuring with RSEQ=n. And indeed with CONFIG_VCPU_DOMAIN=n, the implementation of task_mm_vcpu_id() uses raw_smp_processor_id(), so if we ever want to expose this as an explicit Kconfig option, we can, but I&#x27;m not convinced this is a good idea.<br> <p> It&#x27;s unclear to me whether there would be any overall gain in disabling this feature on systems that have a user-space that make use of it. The memory allocators (glibc, tcmalloc) will be some of the first heavy users, so I expect we will end up in a situation where having the VCPU_DOMAIN feature enabled will actually bring performance benefits to the overall system (including user-space) due to improved memory allocation/access locality.<br> <p> Also you are presuming that the virtual CPU IDs will bring &quot;negligible&quot; performance benefits on systems with few cores but with large amount of memory. I would like to see numbers here, because even though a system has a lot of memory, the locality of cache accesses still matters, and I expect that having the memory allocator pools spread over fewer vcpu ids (compared to number of possible cpus) will provide significant gains on workloads that have few concurrently running threads that migrate between cores.<br> <p> You are also presuming that virtual CPU IDs bring a 2% performance degradation. Is that number made up or did you benchmark the patch series discussed in the article ?<br> </div> Tue, 01 Mar 2022 01:34:40 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886417/ https://lwn.net/Articles/886417/ calumapplepie <div class="FormattedComment"> For those ricers who want every last gram of performance, wouldn&#x27;t it make sense to allow a compilation option disabling the virtual CPU IDs?<br> <p> Obviously, more compile options is inadvisable in general, but on a system with only a few cores and a fairly large amount of memory, the benefits from virtual CPU ids are negligible, but that 2% performance change is doesn&#x27;t change in relative magnitude. The option wouldn&#x27;t need to be complex: just make the virtual CPU ID the same as the real one, and update both parts of the structure simultaneously. It&#x27;s really easy to implement: wrap all the V_CPU logic in a #ifndef, and add a #ifdef assignment from the CPU id to the V_CPU. No distribution will enable it by default, but ricers and embedded programmers probably will.<br> <p> If you want to be extra nice, this optimization could be automatically enabled at boot on all machines with 8 or fewer cores and no CPU hotplug (eg, my laptop&#x27;s quad-core processor with SMT on). That&#x27;d be significantly harder than just adding a few #ifdef statements, but it&#x27;d deliver a minor speed improvement to a lot of users.<br> <p> (not a kernel dev, so there might be some egregious flaw in my reasoning)<br> </div> Mon, 28 Feb 2022 22:52:31 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886392/ https://lwn.net/Articles/886392/ compudj <div class="FormattedComment"> If an application has few threads, using either TLS or a per-vcpu-id approach should typically provide similar results, perhaps except on NUMA systems: in this situation the per-vcpu-id approach would help reducing the amount of CPU affinity tweaks required to provide good NUMA locality of TLS accesses.<br> <p> The major use-case where the vcpu-id provides a clear gain is for applications with many threads which run on a subset of the system&#x27;s cores, through use of cgroup cpusets or sched affinity. This kind of workload is typical of applications running in containers on machines that have a large number of physical cores. In this case, neither a per-core nor a per-thread approach provides an efficient use of the system&#x27;s memory.<br> <p> But there are also other scenarios where the virtual CPU IDs improve things. For instance, even a single-threaded application running in a NUMA system can leverage the virtual CPU IDs to make sure all per-vcpu-id data structure accesses are NUMA-node-local.<br> </div> Mon, 28 Feb 2022 18:28:46 +0000 Extending restartable sequences with virtual CPU IDs https://lwn.net/Articles/886387/ https://lwn.net/Articles/886387/ Bigos <div class="FormattedComment"> Aren&#x27;t programs that don&#x27;t use too many threads better served by just using Thread Local Storage? I always thought that restartable sequences were a tool to reduce the number of &quot;aggregators&quot; (e.g. counters) for software that was running more threads than there were CPUs.<br> </div> Mon, 28 Feb 2022 17:44:34 +0000