SMP: Introduce a new global IRQ clearing logic and tasklist protection.

The previous implementation of clearing global IRQ in sched_addreadytorun()
and sched_removereadytorun() was done too early. As a result, nxsem_post()
would have a chance to enter the critical section even nxsem_wait() is
still not in blocked state. This patch moves clearing global IRQ controls
from sched_addreadytorun() and sched_removereadytorun() to sched_resumescheduler()
to ensure that nxsem_post() can enter the critical section correctly.

For this change, sched_resumescheduler.c is always necessary for SMP configuration.
In addition, by this change, task_exit() had to be modified so that it calls
sched_resumescheduler() because it calls sched_removescheduler() inside the
function, otherwise it will cause a deadlock.

However, I encountered another DEBUGASSERT() in sched_cpu_select() during
HTTP streaming aging test on lc823450-xgevk. Actually sched_cpu_select()
accesses the g_assignedtasks which might be changed by another CPU. Similarly,
other tasklists might be modified simultaneously if both CPUs are executing
scheduling logic. To avoid this, I introduced tasklist protetion APIs.

With these changes, SMP kernel stability has been much improved.

Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
This commit is contained in:
Masayuki Ishikawa
2018-01-31 11:23:22 +09:00
parent 3521aaf944
commit d295f11a3a
11 changed files with 259 additions and 16 deletions

View File

@@ -97,6 +97,14 @@ int task_exit(void)
(void)sched_removereadytorun(dtcb);
rtcb = this_task();
#ifdef CONFIG_SMP
/* Because clearing the global IRQ control in sched_removereadytorun()
* was moved to sched_resume_scheduler(). So call the API here.
*/
sched_resume_scheduler(rtcb);
#endif
/* We are now in a bad state -- the head of the ready to run task list
* does not correspond to the thread that is running. Disabling pre-
* emption on this TCB and marking the new ready-to-run task as not