LWN: Comments on "User-space interrupts" https://lwn.net/Articles/871113/ This is a special feed containing comments posted to the individual LWN article titled "User-space interrupts". en-us Sun, 31 Aug 2025 17:14:04 +0000 Sun, 31 Aug 2025 17:14:04 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net User-space interrupts https://lwn.net/Articles/990650/ https://lwn.net/Articles/990650/ intelfx <div class="FormattedComment"> Like Cyberax said... this is exactly the instruction(s) that the kernel runs in each and every idle loop :-) And, incidentally, this is exactly how cpuidle works at least on x86 — via different "wait for interrupt" instructions.<br> </div> Wed, 18 Sep 2024 07:09:55 +0000 User-space interrupts https://lwn.net/Articles/990649/ https://lwn.net/Articles/990649/ Cyberax <div class="FormattedComment"> x86 has it: <a href="https://en.wikipedia.org/wiki/HLT_">https://en.wikipedia.org/wiki/HLT_</a>(x86_instruction)<br> </div> Wed, 18 Sep 2024 06:43:25 +0000 User-space interrupts https://lwn.net/Articles/990648/ https://lwn.net/Articles/990648/ renox <div class="FormattedComment"> IMHO the CPU should provide a 'wait for interrupt' instruction (maybe with different power saving level configurable).<br> </div> Wed, 18 Sep 2024 06:23:30 +0000 User-space interrupts https://lwn.net/Articles/890239/ https://lwn.net/Articles/890239/ pskocik <div class="FormattedComment"> Looking forward to this.<br> <p> I feel the interface/semantics should follow signals as closely as possible. In particular I strongly think those interrupts should break system calls with EINTR if it&#x27;s not possible to choose (like with SA_RESTART in the case of signals). You can always get SA_RESTART semantics by looping around a EINTR-returning systemcalls (possibly in a library) but if a hung system call won&#x27;t return, there&#x27;s nothing userspace can do to react to a signal/interrupt.<br> <p> As for the fd interface—I don&#x27;t know if it&#x27;s the right one. Intuitively it feels like threads should be able to interrupt themselves via their id (so there could be an interrupt version of pthread_kill). Same-process threads implicitly via pid_t and foreign threads via pid_t after acquiring permission somehow, preferable without involving fds, but maybe that&#x27;s wrong intuition.<br> <p> I&#x27;m curious what other similarities and disimilarities with signals there will be. Blocking masks? SA_NODEFER? alternative stacks?<br> <p> I also hear the Linux kernel cannot use the x86_64 red zone because interrupts would clobber it. Will these userspace interrupts be able to respect the red zone?<br> </div> Tue, 05 Apr 2022 11:13:41 +0000 User-space interrupts https://lwn.net/Articles/875272/ https://lwn.net/Articles/875272/ mcortese Isn't an important piece missing here? This patch set must impose additional burden on every context switch in order to keep track of where the receiving process is actually running. Inter-process communications might get some benefits, but has anyone evaluated the penalty for the rest of the code? Sat, 06 Nov 2021 10:04:21 +0000 User-space interrupts https://lwn.net/Articles/872982/ https://lwn.net/Articles/872982/ nybble41 <div class="FormattedComment"> IMHO the unnecessary complication here is that &quot;regular files&quot; are treated specially. When your &quot;regular file&quot; could be backed by a network filesystem, FUSE, NBD, etc. it really ought to be considered more like a socket, subject to potential short reads and returning EINTR on signals whether or not any data has been read.<br> <p> Users generally expect to be able to use sockets and pipes in place of regular files, e.g. using process substitution in Bash or named FIFOs or Unix-domain sockets in the filesystem, or arbitrary paths under /proc/$PID/fd/. Unless there is a good reason to require capabilities specific to regular files, for example lseek() or mmap()—or the application creates the file itself with O_EXCL—then applications ought to expect that read() and write() may process less data than requested even if the normal case involves regular files.<br> <p> As for the longjmp() approach, that only works because the kernel backs out of the blocking call before invoking the signal handler. (A longjmp() call from a signal handler can&#x27;t perform a non-local return out of arbitrary *kernel* stack frames.) At that point it&#x27;s mostly a matter of policy whether the kernel restarts the system call after the handler returns or just returns EINTR to the caller—either always restarting or always returning EINTR would not simplify the kernel signficantly—and in general matters of policy are best left to application or library code rather than the kernel. Wrapping every non-interruptable read() in a loop to restart it until you get all the data you wanted is not substantially more code, or more *complex* code, than wrapping every read() which you might want to interrupt in a call to setjmp() and communicating that fact to the signal handler so it can decide whether to call longjmp().<br> <p> POSIX also has these caveats regarding longjmp() from a signal handler:<br> <p> <font class="QuotedText">&gt; It is recommended that applications do not call longjmp() or siglongjmp() from signal handlers. To avoid undefined behavior when calling these functions from a signal handler, the application needs to ensure one of the following two things: … After the call to longjmp() or siglongjmp() the process only calls async-signal-safe functions and does not return from the initial call to main(). … Any signal whose handler calls longjmp() or siglongjmp() is blocked during *every* call to a non-async-signal-safe function, and no such calls are made after returning from the initial call to main().</font><br> <p> It would be difficult to guarantee either of these restrictions are met in a complex application with many library dependencies. For example, if you return from a signal handler with longjmp() and then call printf() without masking every signal whose handler could call longjmp() then you&#x27;ve already broken both of those rules and invoked undefined behavior.<br> </div> Thu, 14 Oct 2021 19:51:50 +0000 User-space interrupts https://lwn.net/Articles/872969/ https://lwn.net/Articles/872969/ anton I found writing a signal handler more of a challenge than performing the longjmp() (and I don't remember ever having a bug due to the longjmp()). The problem is that asynchronous signals can be invoked anywhere, including in the middle of updating some data structure, so you have a chance of corrupting the data structure if you longjmp() out of a signal handler for an asynchronous signal. Thu, 14 Oct 2021 17:18:19 +0000 User-space interrupts https://lwn.net/Articles/872967/ https://lwn.net/Articles/872967/ anton Unix has the very good idea that everything is a file. One of the benefits is that you can write some general routine on top of the system calls, and it is useful for all kinds of things. This admittedly does not work all the time, but we should strive for it. <p>In the present case, requiring the general routine to know whether it is used on a file that can result in EINTR, and how to behave in that case (which is very likely application-dependent) breaks modularity. <p>The application and its signal handler know how to deal with the situation, and the longjmp() approach is a good one in that sense. Of course, leaving an asynchronous signal with longjmp() has its dangers, but that's still the way we chose in Gforth (where asynchronous signals are rare). Thu, 14 Oct 2021 17:13:18 +0000 User-space interrupts https://lwn.net/Articles/872901/ https://lwn.net/Articles/872901/ mpr22 <div class="FormattedComment"> <font class="QuotedText">&gt; But I don&#x27;t think that would be *clearly* better than the current situation. Maybe marginally better - I don&#x27;t know.</font><br> <p> When an idea involves normalizing the use of longjmp() in code written by mere mortals, that creates in my mind the (theoretically, but probably not practically, rebuttable) presumption that the idea is absolutely terrible.<br> </div> Wed, 13 Oct 2021 23:23:25 +0000 User-space interrupts https://lwn.net/Articles/872899/ https://lwn.net/Articles/872899/ neilbrown <div class="FormattedComment"> <font class="QuotedText">&gt; Why should every user of read() have to deal with EINTR? </font><br> <p> It&#x27;s not &quot;every user of read()&quot;, but only every user of read() reading from a file descriptor on which reads can block.<br> That does NOT include regular files - mainly char devices and sockets.<br> When you read from something that can block, you usually want more than you can be sure of getting in a single read. You&#x27;ll usually need to be prepared to read some more anyway (not always, but often).<br> So you need to be prepared for a short read, and handling EINTR as well is not a whole lot more effort.<br> <p> You certainly *could* have a platform where read() always retries EINTR, and signal handlers have to use longjmp if they want to abort a system call. But I don&#x27;t think that would be *clearly* better than the current situation. Maybe marginally better - I don&#x27;t know.<br> <p> </div> Wed, 13 Oct 2021 22:47:44 +0000 User-space interrupts https://lwn.net/Articles/872786/ https://lwn.net/Articles/872786/ madscientist <div class="FormattedComment"> That doesn&#x27;t work: the user needs to deal with the signal that was received, and since signal handlers are so restricted it usually needs to happen in &quot;normal context&quot; not inside the handler. And after dealing with it, they might or might not want to restart the read(). Perhaps the program got a SIGCHLD and before we restart reading we need to deal with our dead child process. Or maybe the interrupt was SIGINT and we want to shut down the process in a reliable way after doing cleanup, so the signal handler set a flag but now we definitely don&#x27;t want to re-enter the read() at all.<br> </div> Wed, 13 Oct 2021 13:19:20 +0000 User-space interrupts https://lwn.net/Articles/872770/ https://lwn.net/Articles/872770/ anton Looking at the wrapper of read() (one of the system calls that , it does not handle ERESTART, and ERESTART is not documented as an error returned from read(), while EINTR is. <p>Why do you think that a blocking read() should not just continue (by restarting the system call) if the signal handler just returns after doing whatever it was doing? Why should every user of read() have to deal with EINTR? Wed, 13 Oct 2021 06:37:27 +0000 User-space interrupts https://lwn.net/Articles/872769/ https://lwn.net/Articles/872769/ anton In this scenario the signal will be handled right after the system call (not the wrapper) returns, i.e., immediately. The default for SIGHUP is to terminate the process, so the parent process can reread the configuration file and restart the process (just one example on how to deal with that). Wed, 13 Oct 2021 05:51:27 +0000 User-space interrupts https://lwn.net/Articles/872759/ https://lwn.net/Articles/872759/ neilbrown <div class="FormattedComment"> Your description of EINTR roughly matches my understanding of ERESTART. <br> <p> In many cases a syscall that returns EINTR should *not* be restarted. A blocking read is an obvious case. The application should be given the opportunity to choose whether to restart.<br> It *might* be possible for a platform (such as python) to require that syscalls which cannot be restarted don&#x27;t get used. e.g. reads must be non-blocking. But that is a higher-level design choice than the libc syscall wrapper.<br> <p> </div> Tue, 12 Oct 2021 23:45:20 +0000 User-space interrupts https://lwn.net/Articles/872737/ https://lwn.net/Articles/872737/ mpr22 <div class="FormattedComment"> Imagine a daemon in an call to select() with a long or infinite timeout on a collection of sockets, or in a blocking read() on a socket.<br> <p> Imagine further that you send that daemon SIGHUP, telling it to reload its configuration files.<br> <p> Do you really want it to wait until it receives its next packet before reloading its configuration files? After all, your config change might mean it needs to close one or more of the sockets it&#x27;s currently waiting on and/or open new sockets.<br> <p> I don&#x27;t.<br> <p> I&#x27;d much rather that its signal handler for SIGHUP just sets a flag saying &quot;config must be reloaded&quot;, and that the system call wrapper then returns -1 and sets errno to EINTR, so that my daemon can check its config-reload flag and go &quot;oh hey I&#x27;ve been reconfigured&quot;.<br> </div> Tue, 12 Oct 2021 22:54:09 +0000 User-space interrupts https://lwn.net/Articles/872731/ https://lwn.net/Articles/872731/ anton <blockquote> EINTR is annoying to handle from userspace, so much so that some languages (Python at least) just transparently handle it for you. </blockquote> My understanding of EINTR (especially after reading Gabriel's Worse-is-better paper) is that it's too complicated to deal with the situation (dealing with a signal) in the kernel, so the kernel returns to user space with EINTR, the signal can be delivered, and afterwards user space sees the EINTR and restarts the system call. <p>Based on this understanding, I would expect the system-call wrapper to deal with EINTR, i.e., higher-level user programs should never see it. But strangely, AFAIK the system-call wrappers just deliver EINTR to the higher-level user code. Why? Is my understanding of EINTR wrong? Tue, 12 Oct 2021 21:57:57 +0000 How does CPU state save/restore work with user interrupts? https://lwn.net/Articles/872314/ https://lwn.net/Articles/872314/ tpo <div class="FormattedComment"> Oh! I see, thanks a lot for helping my understanding Ben!<br> <p> Nevertheless the mechanisms looks quite tricky in practice: the inter-CPU communication/synchronization needs to be flawless otherwise it seems like anarchy and chaos could ensue... let&#x27;s hope for rock solid CPU engineering!<br> </div> Fri, 08 Oct 2021 20:14:38 +0000 User-space interrupts https://lwn.net/Articles/872305/ https://lwn.net/Articles/872305/ BenHutchings <div class="FormattedComment"> Plus you can only have one handler function per thread (or process? it&#x27;s not clear). So there will have to be some definitive user-space library (not necessarily the C library) to manage this resource.<br> </div> Fri, 08 Oct 2021 19:00:44 +0000 How does CPU state save/restore work with user interrupts? https://lwn.net/Articles/872304/ https://lwn.net/Articles/872304/ BenHutchings <div class="FormattedComment"> The receiving thread has to already be running on a different CPU, for the interrupt to be delivered directly. If any context switch is needed, it&#x27;s mediated by the kernel, unless I&#x27;ve very much misunderstood.<br> </div> Fri, 08 Oct 2021 18:57:18 +0000 How does CPU state save/restore work with user interrupts? https://lwn.net/Articles/872300/ https://lwn.net/Articles/872300/ tpo <div class="FormattedComment"> I&#x27;m confused:<br> <p> <font class="QuotedText">&gt; [user interrupts] deliver[s] signals directly to user space, bypassing the kernel to achieve lower latency. [...] interprocess [...]</font><br> <p> As far as I understand an interrupt on Intel architectures will essentially only store the PC/IP to the stack. To save/restore of the rest of the CPU registers is up to the interrupt handler. Similar for the TLB and the process&#x27; memory map.<br> <p> Enter user interrupts where a process can trigger an interrupt without going through the kernel.<br> <p> So who will do the CPU state save/restore? The process itself in its own interrupt handler? Thus it will be able to set up random virtual memory maps for itself? And if the interrupting process forgets to flush CPU state, then that will be a information leak from the interrupting process to the interrupted?<br> <p> What is it that I am missing?<br> </div> Fri, 08 Oct 2021 17:03:17 +0000 User-space interrupts https://lwn.net/Articles/872228/ https://lwn.net/Articles/872228/ dancol <div class="FormattedComment"> <font class="QuotedText">&gt; Here, vector is a number between zero and 63; one file descriptor can be created for each vector.</font><br> <p> Ugh. So do I understand correctly that we have yet another process-wide resource --- uipi vector numbers in this case --- not centrally allocated by any process-wide authority? How is a shared library supposed to know what vector number to use? Should it guess? What if two libraries do that?<br> <p> Either the vector number namespace needs to be expanded or libc needs to grow an allocator.<br> </div> Fri, 08 Oct 2021 00:34:43 +0000 User-space interrupts https://lwn.net/Articles/872088/ https://lwn.net/Articles/872088/ wahern <div class="FormattedComment"> Now that Intel has lost the lead in silicon and raw performance, they&#x27;re focusing on specialized hardware features that can directly benefit highly specific aspects of the software engineering problem space, particularly those aspects most important to their biggest customers (e.g. Google and Facebook application fleets, cloud hosting providers, etc), while also promoting vendor lock-in. Of course, the stagnation in clock rates and the weight of Amdahl&#x27;s law also promote this shift. But we&#x27;ve seen this shift to specialized processor features many times before, most recently with HP and especially Sun as they struggled to compete with Intel. Many of Intel&#x27;s recent hardware features are conspicuous for leveraging peculiarities of their ISA and architecture, for example TSX.<br> <p> I don&#x27;t know how self-aware Intel&#x27;s strategies are, but it matters very little as their strategic options are strongly dictated by classic market dynamics. You can easily predict the directions they&#x27;ll take, though that&#x27;s not the same thing as predicting their success, and definitely not a prediction of their imminent demise.<br> <p> </div> Thu, 07 Oct 2021 03:17:30 +0000 User-space interrupts https://lwn.net/Articles/872087/ https://lwn.net/Articles/872087/ wahern <div class="FormattedComment"> Ah, the eternal dance between interrupts and polling. It plays out across the entire design space of hardware and software, with preferences seasonly shifting according to predominating concerns and constraints, but rarely aligning even between adjacent spaces. The majority of people working on internet application software might know this dance as events vs threads, and people who implement such frameworks eventually (hopefully) come to understand that it&#x27;s turtles all the way down--thread scheduler could be based on events/signals/interrupts, which in turn might be triggered by some blocking/waiting/polling mechanism, etc. Processes, signals, actors, CSP, coroutines, even banalities like call stacks, are all just variations on the same basic theme centering around questions of state and control flow management and their reification. They sometimes purported to be the final, concluding step in the dance, at least for large swathes of the problem space, yet invariably the dance continued without missing a beat.<br> <p> There&#x27;s no right answer except that it would especially harmonious and pleasing if a user-space interrupts facility was merged at the same time as Google&#x27;s user-space context switching patches for its User-Managed Concurrency Groups (UCMG) framework: <a href="https://lwn.net/Articles/856816/">https://lwn.net/Articles/856816/</a> An earlier incarnation, SwitchTo, is described at <a href="https://pdxplumbers.osuosl.org/2013/ocw/system/presentations/1653/original/LPC%20-%20User%20Threading.pdf">https://pdxplumbers.osuosl.org/2013/ocw/system/presentati...</a> (<a href="https://web.archive.org/web/20200926200828/https://pdxplumbers.osuosl.org/2013/ocw/system/presentations/1653/original/LPC%20-%20User%20Threading.pdf">https://web.archive.org/web/20200926200828/https://pdxplu...</a>).<br> <p> </div> Thu, 07 Oct 2021 02:52:24 +0000 User-space interrupts https://lwn.net/Articles/871752/ https://lwn.net/Articles/871752/ taladar <div class="FormattedComment"> Another half-baked Intel CPU feature that promises performance gains? Sounds to me as if Intel hasn&#x27;t really learned much from overly focussing on performance at the cost of correctness and security in the past.<br> </div> Mon, 04 Oct 2021 09:23:11 +0000 User-space interrupts https://lwn.net/Articles/871702/ https://lwn.net/Articles/871702/ Bigos <div class="FormattedComment"> I think the idea is: when two threads are running at the same time on different CPUs one can interrupt the other at an order of magnitude lower latency than the alternatives. The thread might be in the middle of execution of a long running task that does not touch any syscalls. And if the receiving thread is not running, the latency is not worse.<br> <p> User mode scheduling (aka &quot;green threads&quot;) was given as an example use case. If I understand correctly, one thread can preempt the other using a userspace interrupt. The interrupt handler can then modify the state so that on return something else is called, similar to how kernel scheduler works, but without any context switches. However, green threads are usually used when scheduling small short-living (or often-waiting) tasks, so cooperative preemption is enough. And when forceful preemption is necessary, it happens seldom enough for it not to be a bottleneck.<br> <p> Jens Axboe mentioned io_uring cq notification [1], though that is about kernel -&gt; userspace which has not been implemented yet.<br> <p> There might be a better use case example that I am not thinking about. In fact, this has been stated as one of the issues on the mailing list [2].<br> <p> At first, I wanted to point out that userspace RCU (URCU) could be a possible use case as well, but that was already resolved by membarrier() syscall years ago [3]. However, userspace interrupts might improve the performance of this even without broadcast support.<br> <p> [1] <a href="https://lwn.net/ml/linux-kernel/ecf3cf2e-685d-afb9-1a5d-1382714cc60c@kernel.dk/">https://lwn.net/ml/linux-kernel/ecf3cf2e-685d-afb9-1a5d-1...</a><br> [2] <a href="https://lwn.net/ml/linux-kernel/456bf9cf-87b8-4c3d-ac0c-7e392bcf26de@www.fastmail.com/">https://lwn.net/ml/linux-kernel/456bf9cf-87b8-4c3d-ac0c-7...</a><br> [3] <a href="https://lwn.net/Articles/369567/">https://lwn.net/Articles/369567/</a><br> </div> Sun, 03 Oct 2021 18:35:18 +0000 User-space interrupts https://lwn.net/Articles/871654/ https://lwn.net/Articles/871654/ kepstin <div class="FormattedComment"> I&#x27;m kinda confused about why hardware support is needed for this. For normally scheduled programs, as likely as not, the process being &quot;interrupted&quot; isn&#x27;t actually running, so wouldn&#x27;t the kernel need to step in and schedule the process before the interrupt could be delivered anyways? What&#x27;s the benefit over a syscall there? <br> <p> Or... Is this primarily for real time processes maybe? If the processes are carefully scheduled and known to be running concurrently on different cpus, I guess a direct userspace interrupt would be a win for latency. <br> </div> Sun, 03 Oct 2021 02:25:23 +0000 User-space interrupts https://lwn.net/Articles/871580/ https://lwn.net/Articles/871580/ nybble41 <div class="FormattedComment"> Another thread in the same process can already change memory (and mappings) while the first thread is in a system call, either because a reschedule occurred during the system call or because the other thread is running on a different CPU. A signal handler doesn&#x27;t seem like it would change anything in that regard.<br> </div> Fri, 01 Oct 2021 16:30:00 +0000 User-space interrupts https://lwn.net/Articles/871537/ https://lwn.net/Articles/871537/ mathstuf <div class="FormattedComment"> The handler could twiddle with memory the syscall is working with from the userspace side, no? You&#x27;ll need a context swap at least anyways so the handler has the right memory mappings.<br> </div> Fri, 01 Oct 2021 13:46:44 +0000 User-space interrupts https://lwn.net/Articles/871533/ https://lwn.net/Articles/871533/ droundy <div class="FormattedComment"> Would it not be possible to service the interrupt and then finish the system call? Or would that put too strong a constraint on what could be done by the handler?<br> </div> Fri, 01 Oct 2021 12:10:12 +0000 User-space interrupts https://lwn.net/Articles/871449/ https://lwn.net/Articles/871449/ NYKevin <div class="FormattedComment"> <font class="QuotedText">&gt; Mehta closed the session (which was running out of time) by asking what should happen when the recipient is blocked in a system call. As mentioned, the current patch set waits for the system call to return before delivering the interrupt. Should the behavior be changed to be closer to signals, with the interrupt delivered immediately and the system call returning with an EINTR status? Nobody had an opinion to share on that question, so the session ended there.</font><br> <p> IMHO it depends on multiple factors:<br> <p> * EINTR is annoying to handle from userspace, so much so that some languages (Python at least) just transparently handle it for you. But you already have to handle it anyway, unless you&#x27;re exclusively doing SIG_IGN/SIG_DFL for all signals.<br> * The &quot;wait for something to happen&quot; syscalls (nanosleep, epoll_wait, etc.) should probably be interrupted, regardless of what is decided for other syscalls.<br> * Since this is supposed to be a &quot;low latency&quot; mechanism, for when signals aren&#x27;t fast enough, it would be very odd if you had to wait around for the kernel before you could get the interrupt, given that signals actually do interrupt the kernel...<br> </div> Thu, 30 Sep 2021 20:11:14 +0000