I'm imagining a much simpler scenario (for two CPUs):
1. High-priority task A takes a mutex and runs for some time without going to sleep.
2. Low-priority task B tries to take the mutex and spins, since A is running. This is where we lose latency, because...
3. ...while B spins, it can't be preempted, so a medium-priority task C can't run on either of CPUs, even if there is some work for it.
I presume, I'm missing something obvious and would be glad to know what it is.
Posted Aug 5, 2009 21:24 UTC (Wed) by PaulMcKenney (subscriber, #9624)
[Link]
OK, you lost me on this one. Why can't task B be preempted while spinning? What am I missing here?
The realtime preemption endgame
Posted Aug 5, 2009 21:43 UTC (Wed) by tertium (subscriber, #56169)
[Link]
I was actually looking at the following phrase in the article: "Code holding spinlocks also cannot be preempted; doing so would cause serious latencies (at best) or deadlocks." Am I confused?
The realtime preemption endgame
Posted Aug 5, 2009 22:17 UTC (Wed) by tertium (subscriber, #56169)
[Link]
Indeed, it seems I am: "code holding a spinlock" != "code spinning". My apologies.
By the way, in your scenario (if I'm not off the mark again) at the step 5, the task A wouldn't spin, since B isn't running. Instead, A would block immediately, awakening B and taking the lock.
The realtime preemption endgame
Posted Aug 5, 2009 22:47 UTC (Wed) by PaulMcKenney (subscriber, #9624)
[Link]
Exactly! :-)
The realtime preemption endgame
Posted Aug 7, 2009 15:49 UTC (Fri) by dvhart (guest, #19636)
[Link]
It is indeed a balancing act. Testing has shown however that spinning for a short while can be preferable to at least 2 additional context switches (figure 25us or so each). See kernel/rtmutex.c adaptive_wait() for details, but basically we sping until one of the following occurs: we get the lock, the owner changes, or the owner goes to sleep.