From af92a67fc52271cd389b472ef921e9d3b6f7b8e4 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 29 Dec 2016 08:53:31 -0600 Subject: [PATCH] SMP: Use irq_cpu_locked() in sched_mergepending() --- sched/sched/sched_mergepending.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sched/sched/sched_mergepending.c b/sched/sched/sched_mergepending.c index 863eb73c27..15e87ce99c 100644 --- a/sched/sched/sched_mergepending.c +++ b/sched/sched/sched_mergepending.c @@ -48,6 +48,7 @@ # include #endif +#include "irq/irq.h" #include "sched/sched.h" /**************************************************************************** @@ -196,15 +197,16 @@ bool sched_mergepending(void) FAR struct tcb_s *tcb; bool ret = false; int cpu; + int me; /* Remove and process every TCB in the g_pendingtasks list. * - * This function is only called in the context where locking is known to - * disabled on one CPU. However, we must do nothing if pre-emption is - * still locked because of actions of other CPUs. + * Do nothing if (1) pre-emption is still disabled (by any CPU), or (2) if + * some CPU other than this one is in a critical section. */ - if (!spin_islocked(&g_cpu_schedlock)) + me = this_cpu(); + if (!spin_islocked(&g_cpu_schedlock) && !irq_cpu_locked(me)) { /* Find the CPU that is executing the lowest priority task */ @@ -243,7 +245,7 @@ bool sched_mergepending(void) * Check if that happened. */ - if (spin_islocked(&g_cpu_schedlock)) + if (spin_islocked(&g_cpu_schedlock) || irq_cpu_locked(me)) { /* Yes.. then we may have incorrectly placed some TCBs in the * g_readytorun list (unlikely, but possible). We will have to