LWN: Comments on "Wait/wound mutexes" https://lwn.net/Articles/548909/ This is a special feed containing comments posted to the individual LWN article titled "Wait/wound mutexes". en-us Sat, 18 Oct 2025 01:08:10 +0000 Sat, 18 Oct 2025 01:08:10 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net Nesting wait/wound mutexes? https://lwn.net/Articles/558742/ https://lwn.net/Articles/558742/ vomlehn <div class="FormattedComment"> I can certainly see that notification that you have to unlock currently held mutexes to avoid a deadlock is a Good Thing and could simplify life. Still, given that you may have to undo, and then redo, work when you unlock an m/m mutex and then reacquire it, I am left with the question of knowing how far you *have to* back off in order to avoid a deadlock. It would be nice if you didn't have to release every single m/m mutex that you hold.<br> <p> It may be the case that, as a practical matter, this is not a performance issue. I can see, however, a maintenance issue. One subsystem may acquire a m/m mutex, then call another subsystem that acquired a different m/m mutex. This M/M mutex implementation implies that the called subsystem will have to know that the caller holds an m/m mutex and return to that subsystem (or use a callback to that subsystem) to release the first mutex. Ick.<br> <p> I can conceive of the m/m mutex code keeping track of the m/m mutexes held by a given task and providing feekback on whether any more mutexes need to be released, which simplifies the problem a little from the performance perspective.<br> <p> All-in-all, I'm not sure this is ready for prime time.<br> </div> Sat, 13 Jul 2013 03:22:40 +0000 They're mutexes, Jim, but not as we know them https://lwn.net/Articles/550772/ https://lwn.net/Articles/550772/ dlang <div class="FormattedComment"> It may be "only an implementation detail" in that the user of the API never deals with the sequence number.<br> <p> But this detail is critical to avoiding the risk of permanent starvation of some thread.<br> </div> Wed, 15 May 2013 20:49:58 +0000 They're mutexes, Jim, but not as we know them https://lwn.net/Articles/550677/ https://lwn.net/Articles/550677/ mlankhorst <div class="FormattedComment"> Correct. The current implementation preserves the sequence number. But it's an implementation detail, the user of the api will never have to work with the sequence numbers directly.<br> </div> Wed, 15 May 2013 13:45:07 +0000 They're mutexes, Jim, but not as we know them https://lwn.net/Articles/550449/ https://lwn.net/Articles/550449/ ksandstr <div class="FormattedComment"> The distinct ordering of locks is required to prevent the client from turning a set of N locks, out of which M are required, into a very expensive spinlock; the low-level idea being that the lock that violates ordering (and generates the EDEADLK status) is a different one each time, and that its being locked may end up not being due to the current client's other locks. WW mutexes prevent this by sleeping the backing-off client until the conflicting mutex has been released at least once, which is strictly required for its progress.<br> <p> But as you say, for algorithms where the needed set of locks cannot change between backout and retry, your solution is adequate. I've found that those algorithms generally aren't candidates for fine-grained locking, though that's neither here or there.<br> <p> Personally, if wait/wound mutexes remove these halfway esoteric concerns from mainstream kernel code (along with the entire idea of lock ordering), I'll be happy as a clam.<br> </div> Mon, 13 May 2013 17:40:05 +0000 They're mutexes, Jim, but not as we know them https://lwn.net/Articles/550147/ https://lwn.net/Articles/550147/ dlang <div class="FormattedComment"> from the article<br> <p> <font class="QuotedText">&gt; But, since the sequence number increases monotonically, a once-wounded thread must eventually reach a point where it has the highest priority and will win out.</font><br> <p> They don't say explicitly that the sequence number is maintained, but I don't see what this would mean otherwise.<br> </div> Sat, 11 May 2013 02:21:12 +0000 They're mutexes, Jim, but not as we know them https://lwn.net/Articles/550137/ https://lwn.net/Articles/550137/ brong <div class="FormattedComment"> Hang on - are you saying that the sequence number you were allocated persists even after you back out and try again?<br> <p> My understanding was that once you're wounded, you have to restart from scratch. If you're restarting with the same (low) sequence number rather than being allocated a brand new one, then I see your point. Otherwise, I see starvation possibilities, the horror.<br> </div> Fri, 10 May 2013 23:44:36 +0000 They're mutexes, Jim, but not as we know them https://lwn.net/Articles/550092/ https://lwn.net/Articles/550092/ dlang <div class="FormattedComment"> <font class="QuotedText">&gt; but it seems the other threads may burn unlimited CPU time attempting to take locks and retrying in pathological cases.</font><br> <p> undefined CPU time, but not unlimited.<br> <p> each thread gets a sequence number when they start trying to get a lock, and when two threads conflict, the one with the lower sequence number wins.<br> <p> As a result, every thread is guaranteed to be able to get the lock in preference to any threads that were first tried to get the lock after it did.<br> <p> This puts a outer bound on the amount of CPU it will waste in the meantime (admittedly, not a bound that you can readily calculate since you don't know how long the locks will be held by processes that have priority over you)<br> </div> Fri, 10 May 2013 19:17:40 +0000 They're mutexes, Jim, but not as we know them https://lwn.net/Articles/550052/ https://lwn.net/Articles/550052/ heijo <div class="FormattedComment"> The procedure can simply be to remember the lock you wanted to take in all previous attempts and start the next attempt by sorting them by lock order and taking them.<br> <p> Eventually you'll succeed, although it may take time quadratic in the total number of locks that may be taken across attempts.<br> <p> Wait/wound on the other hand guarantees that the first-coming thread will progress in linear time in the number of locks, but it seems the other threads may burn unlimited CPU time attempting to take locks and retrying in pathological cases.<br> <p> This could be fixable by having the "later" thread wait directly for all earlier threads to be done, to save power at the expense of latency, although this is probably not an issue in practice.<br> <p> <p> <p> </div> Fri, 10 May 2013 17:08:36 +0000 They're mutexes, Jim, but not as we know them https://lwn.net/Articles/549898/ https://lwn.net/Articles/549898/ ksandstr <div class="FormattedComment"> There are at least two concrete reasons for using wait/wound mutexes over the more common "define a lock ordering, and (very carefully) violate it with try-lock primitives" scheme of fine-grained multiple locking.<br> <p> The first is that a failure to try-lock requires some sort of a fall-back procedure that either doesn't violate locking order, or does so with a different try-lock subject than in previous iterations. Coming up with that procedure is an enormous hassle, and cramps many a concurrent design. Wait/wound mutexes would seem to avoid this hazard by permitting the wounded thread to resume only after the contended mutex has been released at least once.<br> <p> The second is that (depending on the interface) wait/wound mutexes could reduce the "slumbering herd" effect that occurs when a thread holds a number of mutexes but then has to wait on one more, repeating down the tree. (this effect also tends to magnify non-mutex waits through the mutex scheme, making it especially pernicious.) This reduction would happen by having the wounded thread wait for the contended mutex only after releasing its own, thereby allowing sufficiently unrelated threads to proceed unimpeded. The net gain is lower aggregate latency under contention.<br> </div> Thu, 09 May 2013 21:48:20 +0000 Wait/Wake https://lwn.net/Articles/549141/ https://lwn.net/Articles/549141/ jake <div class="FormattedComment"> <font class="QuotedText">&gt; I see two usages intersprinkled, "wake/wound" and "wait/wound".</font><br> <p> Indeed. Typo alert. "wait/wound" is correct, fixed now, thanks.<br> <p> jake<br> </div> Thu, 02 May 2013 21:16:01 +0000 Wait/Wake https://lwn.net/Articles/549136/ https://lwn.net/Articles/549136/ ncm <div class="FormattedComment"> I see two usages intersprinkled, "wake/wound" and "wait/wound". Is this what amounts to a benign disagreement over spelling (I note pronunciation is about the same), or did I miss something? <br> </div> Thu, 02 May 2013 21:07:37 +0000 Wait/wound mutexes https://lwn.net/Articles/549050/ https://lwn.net/Articles/549050/ blackwood <div class="FormattedComment"> I've forgotten to stress that in my big reply to Maarten's comment a bit, so let's reiterate: Current kernels already ship with these mad deadlock-avoiding mutexes, they're simply called reservations instead of w/w mutexes.<br> <p> So we have both code using w/w mutexes, and it's not really a new concept for drivers/gpu/drm. Last paragraphs needs to be updated a bit ;-)<br> </div> Thu, 02 May 2013 09:14:15 +0000 Wait/wound mutexes https://lwn.net/Articles/549047/ https://lwn.net/Articles/549047/ blackwood <div class="FormattedComment"> Yeah, the big reason for pushing these ww mutexes into core code from ttm (where they are called reservations) is to enable cross-device synchronization of dma access to shared buffer objects (aka dma_bufs). Currently access is completely unsynchronized in the kernel, so if userspace doesn't block (which it really shouldn't), displaying a frame rendered on a discrete gpu on the integrated one will horribly tear.<br> <p> Rob Clark started a proposal for dma_fences (now in Maarten's branch), which are attached to each dma_buf taking part in any given gpu render batch (or any other dma op affecting a dma_buf).<br> <p> Now if you naively walk all the dma_bufs, lock each of them one-by-one and attach a new set of fences, races with other threads have a peculiar effect: If you're unlucky you can create a synchronization loop between a bunch of buffers and fences, and since these fences can be fully hw-based (i.e. never wake up the cpu to do the syncing) you'll end up with deadlocked gpus, each waiting on the other.<br> <p> Hw sync/wait deadlocks between different drivers is the kind of fun I don't want to deal with, so we need a multi-object locking scheme which works cross-devices.<br> <p> Note that i915 isn't currently based on ttm (and personally I'm not known as a big fan of ttm), but the proposed ww mutex stuff is massively improved:<br> - not intermingled with all the gpu memroy management craziness ttm also does<br> - sane, clear api (we grade on a curve in gpu-land ...) with decent documentation<br> - _really_ good debug support - while writing the kerneldoc for Maarten's code I've checked whether any kind of interface abuse would be caught. Furthermore we have a slowpath injection debug option to exercise the contended case (-EDEADLK) with single-threaded tests.<br> <p> Now one critique I hear often is "why can't you guys use something simpler?". Reasons against that:<br> - current ttm based drivers (radeon, nouveau, ...) already deal with this complexity. Furthermore gpus tend to die randomly, so all the command submission ioctls for the big drivers (i915, radeon, nouveau) are already fully restartable. Ditching a tiny bit of code to handle the ww mutex slowpath won't sched complexity.<br> - Current drivers rely on the -EALREADY semantics for correctnes. Crazy, I know, but like I've said: We grade on a scale ... Any simple scheme would so need to support this, too. Toghether with the first point you won't really have be able to achieve any reduction in interface complexity for drivers.<br> - Thanks to a big discussion with Peter Zijlstra we have a rather solid plan forward for PI-boosting and bounded lock acquisition in linux-rt.<br> <p> Thus far all the proposed "simple" schemes fall short in one place or the other.<br> <p> Also, cross-device sync with dma_buf/fence isn't the only use-case I see rolling in:<br> - i915 is in desperate need of a finer-grained locking scheme. We run into ugly OOM issues all over the place due to our current "one lock to rule them all" design. We duct-tape over the worst with horrible hacks, but spurious OOMs are still too easy to hit. Moving to a per-object lock scheme using ww mutexes will fix that. Plan B would be to use ttm, but that'd be _really_ disruptive, and I don't like ttm that much.<br> - We're in the process of switching to per-object locking for drm modeset objects, but the complex (and dynamic) graph nature of all the connections poses some interesting issues. Ww mutexes would naturally solve this problem, too.<br> -Daniel<br> </div> Thu, 02 May 2013 09:03:48 +0000 Wait/wound mutexes https://lwn.net/Articles/549042/ https://lwn.net/Articles/549042/ mlankhorst <div class="FormattedComment"> Yeah, the full branch is at <a href="http://cgit.freedesktop.org/~mlankhorst/linux/log/">http://cgit.freedesktop.org/~mlankhorst/linux/log/</a> , with TTM converted and a WIP to do the same on intel and sync shared dma-bufs between radeon/nouveau and intel. The actual sharing part is still a bit hacky, and less reviewed. This is because it involves synchronization between multiples gpu's, which is a step further.<br> </div> Thu, 02 May 2013 08:07:55 +0000 Wait/wound mutexes https://lwn.net/Articles/549040/ https://lwn.net/Articles/549040/ airlied <div class="FormattedComment"> Oh there is code to use it, we have code in the drm TTM layer doing ordered buffer reservations with backoff for deadlocks, and we need something at a higher level for dma-buf to use if we are sharing buffers between multiple GPU drivers or other misc drivers.<br> <p> So Maarten has code to port TTM over to this infrastructure already in a branch, and has posted it to dri-devel previously I think.<br> </div> Thu, 02 May 2013 07:54:34 +0000