mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 12:08:36 +08:00
sched: task: Fix nxtask_exit() for SMP
Summary: - During Wi-Fi audio streaming test, I found a deadlock in nxtask_exit() - Actually, nxtask_exit() was called and tried to enter critical section - In enter_critical_section(), there is a deadlock avoidance logic - However, if switched to a new rtcb with irqcount=0, the logic did not work - Because the 2nd critical section was treated as if it were the 1st one - Actually, it tried to run the deadlock avoidance logic - But nxtask_exit() was called with critical section (i.e. IRQ already disabled) - So the logic did not work as expected because up_irq_restore() did not enable the IRQ. - This commit fixes this issue by incrementing irqcount before calling nxtask_terminate() - Also it adjusts g_cpu_irqlock and g_cpu_lockset Impact: - Affects SMP only Testing: - Tested with spresense:wifi_smp (smp, ostest, nxplayer, telnetd) - Tested with sabre-6quad:smp with QEMU (smp, ostest) - Tested with maix-bit:smp with QEMU (smp, ostest) - Tested with esp32-core:smp with QEMU (smp, ostest) Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
This commit is contained in:
parent
650997e1f6
commit
35c8da34a8
1 changed files with 33 additions and 0 deletions
|
@ -28,6 +28,10 @@
|
|||
|
||||
#include "sched/sched.h"
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
# include "irq/irq.h"
|
||||
#endif
|
||||
|
||||
#include "signal/signal.h"
|
||||
#include "task/task.h"
|
||||
|
||||
|
@ -140,7 +144,36 @@ int nxtask_exit(void)
|
|||
*/
|
||||
|
||||
nxsched_add_blocked(dtcb, TSTATE_TASK_INACTIVE);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* NOTE:
|
||||
* During nxtask_terminate(), enter_critical_section() will be called
|
||||
* to deallocate tcb. However, this would aquire g_cpu_irqlock if
|
||||
* rtcb->irqcount = 0, event though we are in critical section.
|
||||
* To prevent from aquiring, increment rtcb->irqcount here.
|
||||
*/
|
||||
|
||||
if (rtcb->irqcount == 0)
|
||||
{
|
||||
spin_setbit(&g_cpu_irqset, this_cpu(), &g_cpu_irqsetlock,
|
||||
&g_cpu_irqlock);
|
||||
}
|
||||
|
||||
rtcb->irqcount++;
|
||||
#endif
|
||||
|
||||
ret = nxtask_terminate(dtcb->pid, true);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
rtcb->irqcount--;
|
||||
|
||||
if (rtcb->irqcount == 0)
|
||||
{
|
||||
spin_clrbit(&g_cpu_irqset, this_cpu(), &g_cpu_irqsetlock,
|
||||
&g_cpu_irqlock);
|
||||
}
|
||||
#endif
|
||||
|
||||
rtcb->task_state = TSTATE_TASK_RUNNING;
|
||||
|
||||
/* Decrement the lockcount on rctb. */
|
||||
|
|
Loading…
Reference in a new issue