kernel: Don't _arch_switch() to yourself
The SMP testing missed the case where _Swap() decides to return back into the _current. Obviously there is no valid switch handle for the running thread into which we can restore, and everything blows up. (What happened is that the new scheduler code opened up a spot where k_thread_priority_set() does a _reschedule() unconditionally and doens't check to see whether or not it's needed like the old code). But that isn't incorrect! It's entirely possible that _Swap() may find that no thread is runnable except _current (due, for example, to another CPU racing the other thread you expected off to sleep or something). Don't blow up, check and return a noop. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
6040bf7773
commit
c0ba11b281
1 changed files with 12 additions and 10 deletions
|
@ -44,7 +44,7 @@ void _smp_release_global_lock(struct k_thread *thread);
|
|||
static inline unsigned int _Swap(unsigned int key)
|
||||
{
|
||||
struct k_thread *new_thread, *old_thread;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
old_thread = _current;
|
||||
|
||||
|
@ -57,22 +57,24 @@ static inline unsigned int _Swap(unsigned int key)
|
|||
|
||||
new_thread = _get_next_ready_thread();
|
||||
|
||||
old_thread->swap_retval = -EAGAIN;
|
||||
if (new_thread != old_thread) {
|
||||
old_thread->swap_retval = -EAGAIN;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
old_thread->base.active = 0;
|
||||
new_thread->base.active = 1;
|
||||
old_thread->base.active = 0;
|
||||
new_thread->base.active = 1;
|
||||
|
||||
new_thread->base.cpu = _arch_curr_cpu()->id;
|
||||
new_thread->base.cpu = _arch_curr_cpu()->id;
|
||||
|
||||
_smp_release_global_lock(new_thread);
|
||||
_smp_release_global_lock(new_thread);
|
||||
#endif
|
||||
|
||||
_current = new_thread;
|
||||
_arch_switch(new_thread->switch_handle,
|
||||
&old_thread->switch_handle);
|
||||
_current = new_thread;
|
||||
_arch_switch(new_thread->switch_handle,
|
||||
&old_thread->switch_handle);
|
||||
|
||||
ret = _current->swap_retval;
|
||||
ret = _current->swap_retval;
|
||||
}
|
||||
|
||||
irq_unlock(key);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue