kernel/sched: Don't reschedule inside a nested lock
The internal "reschedule" API has always understood the idea that it
might run in a ISR context where it can't swap. But it has always
been happy to swap away when in thread mode, even when the environment
contains an outer lock that would NOT be expecting to swap! As it
happened, the way irq locks are implemented (they store flag state
that can be restored without context) this would "work" even though it
was completely breaking the synchronization promise made by the outer
lock.
But now, with spinlocks, the error gets detected (albeit in a clumsy
way) in debug builds. The unexpected swap triggers SPIN_VALIDATE
failures in later threads (this gets reported as a "recursive" lock,
but what actually happened is that another thread got to run before
the lock was released and tried to grab the same lock).
Fix this so that swap can only be called in a situation where the irq
lock key it was passed would have the effect of unmasking interrupts.
Note that this is a real behavioral change that affects when swaps
occur: it's not impossible that there is code out there that actually
relies on this "lock breaking reschedule" for correct behavior. But
our previous implementation was irredeemably broken and I don't know
how to address that.
Fixes #16273
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
1 file changed