From f859c03325958de48f1c23c64adee538de07572a Mon Sep 17 00:00:00 2001 From: dulibo1 Date: Wed, 17 Apr 2024 17:42:51 +0800 Subject: [PATCH 1/2] sched_smp:adjust the unlock order 1.nxsem_post wake up nxsched_smp_call; 2.stack smp_call_data_s may return; 3.nxsched_smp_call_handler access call_data->lock is not safety; so adjust the unlock order Signed-off-by: dulibo1 --- sched/sched/sched_smp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sched/sched/sched_smp.c b/sched/sched/sched_smp.c index f43cb08ac74a3..94aab391300bd 100644 --- a/sched/sched/sched_smp.c +++ b/sched/sched/sched_smp.c @@ -137,22 +137,22 @@ int nxsched_smp_call_handler(int irq, FAR void *context, ret = call_data->func(call_data->arg); flags = enter_critical_section(); - if (call_data->cookie != NULL) + if (spin_is_locked(&call_data->lock)) { - if (ret < 0) + if (--call_data->refcount == 0) { - call_data->cookie->error = ret; + spin_unlock(&call_data->lock); } - - nxsem_post(&call_data->cookie->sem); } - if (spin_is_locked(&call_data->lock)) + if (call_data->cookie != NULL) { - if (--call_data->refcount == 0) + if (ret < 0) { - spin_unlock(&call_data->lock); + call_data->cookie->error = ret; } + + nxsem_post(&call_data->cookie->sem); } } From 549f0ecd6889ca07fbd4e87672ff133bec9e6beb Mon Sep 17 00:00:00 2001 From: xuxingliang Date: Tue, 16 Jul 2024 14:59:15 +0800 Subject: [PATCH 2/2] sched: handle sched lock in interrupt Signed-off-by: xuxingliang --- sched/sched/sched_smp.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/sched/sched/sched_smp.c b/sched/sched/sched_smp.c index 94aab391300bd..af6c88a4e5ecf 100644 --- a/sched/sched/sched_smp.c +++ b/sched/sched/sched_smp.c @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -61,6 +62,7 @@ struct smp_call_data_s static sq_queue_t g_smp_call_queue[CONFIG_SMP_NCPUS]; static struct smp_call_data_s g_smp_call_data; +static spinlock_t g_smp_call_lock; /**************************************************************************** * Private Functions @@ -86,9 +88,9 @@ static void nxsched_smp_call_add(int cpu, { irqstate_t flags; - flags = enter_critical_section(); + flags = spin_lock_irqsave(&g_smp_call_lock); sq_addlast(&call_data->node[cpu], &g_smp_call_queue[cpu]); - leave_critical_section(flags); + spin_unlock_irqrestore(&g_smp_call_lock, flags); } /**************************************************************************** @@ -119,7 +121,7 @@ int nxsched_smp_call_handler(int irq, FAR void *context, FAR sq_entry_t *next; int cpu = this_cpu(); - irqstate_t flags = enter_critical_section(); + irqstate_t flags = spin_lock_irqsave(&g_smp_call_lock); call_queue = &g_smp_call_queue[cpu]; @@ -132,11 +134,11 @@ int nxsched_smp_call_handler(int irq, FAR void *context, sq_rem(&call_data->node[cpu], call_queue); - leave_critical_section(flags); + spin_unlock_irqrestore(&g_smp_call_lock, flags); ret = call_data->func(call_data->arg); - flags = enter_critical_section(); + flags = spin_lock_irqsave(&g_smp_call_lock); if (spin_is_locked(&call_data->lock)) { if (--call_data->refcount == 0) @@ -157,7 +159,7 @@ int nxsched_smp_call_handler(int irq, FAR void *context, } up_cpu_paused_restore(); - leave_critical_section(flags); + spin_unlock_irqrestore(&g_smp_call_lock, flags); return OK; } @@ -219,13 +221,20 @@ int nxsched_smp_call(cpu_set_t cpuset, nxsched_smp_call_t func, }; FAR struct smp_call_data_s *call_data; - int remote_cpus = 0; + int remote_cpus; int ret = OK; int i; + /* Cannot wait in interrupt context. */ + + DEBUGASSERT(!(wait && up_interrupt_context())); + /* Prevent reschedule on another processor */ - sched_lock(); + if (!up_interrupt_context()) + { + sched_lock(); + } if (CPU_ISSET(this_cpu(), &cpuset)) { @@ -293,6 +302,10 @@ int nxsched_smp_call(cpu_set_t cpuset, nxsched_smp_call_t func, } out: - sched_unlock(); + if (!up_interrupt_context()) + { + sched_unlock(); + } + return ret; }