From d023c70b0605d18829f2ff010a189757d666b7b5 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Thu, 16 Jul 2020 11:11:15 +0200 Subject: [PATCH] cortexm_common: disable IRQ during thread_sched_idle A race condition is present where an IRQ is serviced between the priority increase of the PENDSV and the sleep. When the IRQ is serviced before the WFI sleep, the core will sleep until the next IRQ and the thread activated by the IRQ will not be scheduled until a new IRQ triggers. This commit wraps an IRQ disable and restore around the priority modification and sleep to prevent interrupts from being serviced until the WFI call returns. (cherry picked from commit eec7aa2e4284ca1884e0b2f680c036bebe69e79e) --- cpu/cortexm_common/thread_arch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index 40ea9eb5e7ed..5c40103d5e28 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -460,6 +460,7 @@ void sched_arch_idle(void) * According to [this](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0321a/BIHJICIE.html), * dynamically changing the priority is not supported on CortexM0(+). */ + unsigned state = irq_disable(); NVIC_SetPriority(PendSV_IRQn, CPU_CORTEXM_PENDSV_IRQ_PRIO + 1); __DSB(); __ISB(); @@ -469,5 +470,6 @@ void sched_arch_idle(void) #else __WFI(); #endif + irq_restore(state); NVIC_SetPriority(PendSV_IRQn, CPU_CORTEXM_PENDSV_IRQ_PRIO); }