kernel/sched: Fix race between thread wakeup timeout and abort
Aborted threads will cancel their timeouts, but the timeout subsystem isn't protected under the same lock so it's possible for a timeout to fire just as a thread is being aborted and wake it up unexpectedly. Check the state before blowing anything up. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
8e16012ab7
commit
37866336f9
1 changed files with 13 additions and 8 deletions
|
@ -765,16 +765,21 @@ ALWAYS_INLINE void z_unpend_thread_no_timeout(struct k_thread *thread)
|
|||
/* Timeout handler for *_thread_timeout() APIs */
|
||||
void z_thread_timeout(struct _timeout *timeout)
|
||||
{
|
||||
LOCKED(&sched_spinlock) {
|
||||
struct k_thread *thread = CONTAINER_OF(timeout,
|
||||
struct k_thread, base.timeout);
|
||||
struct k_thread *thread = CONTAINER_OF(timeout,
|
||||
struct k_thread, base.timeout);
|
||||
|
||||
if (thread->base.pended_on != NULL) {
|
||||
unpend_thread_no_timeout(thread);
|
||||
LOCKED(&sched_spinlock) {
|
||||
bool killed = ((thread->base.thread_state & _THREAD_DEAD) ||
|
||||
(thread->base.thread_state & _THREAD_ABORTING));
|
||||
|
||||
if (!killed) {
|
||||
if (thread->base.pended_on != NULL) {
|
||||
unpend_thread_no_timeout(thread);
|
||||
}
|
||||
z_mark_thread_as_started(thread);
|
||||
z_mark_thread_as_not_suspended(thread);
|
||||
ready_thread(thread);
|
||||
}
|
||||
z_mark_thread_as_started(thread);
|
||||
z_mark_thread_as_not_suspended(thread);
|
||||
ready_thread(thread);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue