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:
Andy Ross 2018-05-14 14:46:27 -07:00 committed by Anas Nashif
commit c0ba11b281

View file

@ -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);