-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core/cond.c: expect enabled interrupts in cond_wait() #20940
base: master
Are you sure you want to change the base?
Conversation
48a7c63
to
ae4e094
Compare
This is an issue also in other parts of core, e.g., in core/mutex and msg. |
I think this makes the most sense. |
Indeed, and it seems the fix is the same everywhere. Probably we should also add an arch-independent wrapper around |
The question would be if we should define those functions as interrupt-enabling, and drop the state handling inside them (by doing Any alternative allows mis-use (e.g., by doing |
I don't see a problem with that. Any prior usage that conflicts with this was a bug anyway. |
That would also make sense. Currently, core code does |
This goes deeper. Also stuff like So to revise the definition, it's not only stuff that might block that may not be called with interrupts disabled, but also stuff that might reschedule. And I think this is sensible. The Linux kernel assumes the same for held spinlocks (which on UP do nothing more than disabling interrupts). |
ae4e094
to
a6b2b03
Compare
I would limit the scope of this PR to the original intent, and that is to fix |
Contribution description
Bug 1:
cond_wait()
should never be called with interrupts disabledThe way
cond_wait()
is currently implemented suggests that it may be called with interrupts disabled. Going to sleep with interrupts disabled doesn't quite make sense (although see below) and doesn't work either, as e.g. on ARMthread_yield_higher()
triggers an interrupt. For example, the following assertion is triggered on both ARM and native:My suggestion is to always assume interrupts are enabled. However, there is a valid, albeit hacky use-case for calling
cond_wait()
with interrupts disabled, and that is to guarantee [ condition check + going to sleep ] is atomic w.r. to [ condition set + wake up ] when the latter is in interrupt context:Then, we can fix
cond_wait()
by enabling interrupts just before callingthread_yield_higher()
, and restoring the interrupts state afterwards.I'm not sure which fix is the best. The first one (in the diffs) is more pure, the second enables more use-cases.
Bug 2:
cond_wait()
is callingmutex_unlock()
with interrupts disabledNo matter whether
cond_wait()
is called with interrupts disabled or not, it callsmutex_unlock()
with disabled interrupts.mutex_unock()
will reschedule if a higher priority thread is already blocking on the mutex, leading to the same bug as above. I therefore movedmutex_unlock()
after interrupts are enabled. This still guarantees that [ condition check + going to sleep ] is atomic w.r. to [ condition set + wake up ].