diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c index 6993641fd2726..9eeb4b4c4aa0b 100644 --- a/sched/irq/irq_csection.c +++ b/sched/irq/irq_csection.c @@ -265,6 +265,7 @@ irqstate_t enter_critical_section(void) * no longer blocked by the critical section). */ +try_again_in_irq: if (!irq_waitlock(cpu)) { /* We are in a deadlock condition due to a pending @@ -273,6 +274,24 @@ irqstate_t enter_critical_section(void) */ DEBUGVERIFY(up_cpu_paused(cpu)); + + /* NOTE: As the result of up_cpu_paused(cpu), this CPU + * might set g_cpu_irqset in nxsched_resume_scheduler() + * However, another CPU might hold g_cpu_irqlock. + * To avoid this situation, releae g_cpu_irqlock first. + */ + + if ((g_cpu_irqset & (1 << cpu)) != 0) + { + spin_clrbit(&g_cpu_irqset, cpu, &g_cpu_irqsetlock, + &g_cpu_irqlock); + } + + /* NOTE: Here, this CPU does not hold g_cpu_irqlock, + * so call irq_waitlock(cpu) to acquire g_cpu_irqlock. + */ + + goto try_again_in_irq; } }