kernel/sched: Fix preemption logic
The should_preempt() code was catching some of the "unrunnable" cases but not all of them, opening the possibility of failing to preempt a just-pended thread and thus waking it up synchronously. There are reports of this causing spin loops over k_poll() in the network stack work queues (see #8049). Note that the previous _is_dummy() call is folded into (the somewhat verbosely named) _is_thread_prevented_from_running(), and that the order of tests has been changed/optimized to hopefully catch common cases earlier. Suggested-by: Michael Scott <michael@opensourcefoundries.com> Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
e76ef30aca
commit
43553da9b2
|
@ -114,10 +114,22 @@ int _is_t1_higher_prio_than_t2(struct k_thread *t1, struct k_thread *t2)
|
|||
|
||||
static int should_preempt(struct k_thread *th, int preempt_ok)
|
||||
{
|
||||
/* System initialization states can have dummy threads, never
|
||||
* refuse to swap those
|
||||
/* Preemption is OK if it's being explicitly allowed by
|
||||
* software state (e.g. the thread called k_yield())
|
||||
*/
|
||||
if (!_current || _is_thread_dummy(_current)) {
|
||||
if (preempt_ok) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Or if we're pended/suspended/dummy (duh) */
|
||||
if (!_current || _is_thread_prevented_from_running(_current)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Otherwise we have to be running a preemptible thread or
|
||||
* switching to a metairq
|
||||
*/
|
||||
if (_is_preempt(_current) || is_metairq(th)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -129,18 +141,6 @@ static int should_preempt(struct k_thread *th, int preempt_ok)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Preemption is OK if it's being explicitly allowed */
|
||||
if (preempt_ok) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Otherwise we have to be running a preemptible thread or
|
||||
* switching to a metairq
|
||||
*/
|
||||
if (_is_preempt(_current) || is_metairq(th)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue