diff --git a/arch/arm/src/armv7-a/arm_cpupause.c b/arch/arm/src/armv7-a/arm_cpupause.c index 6c5ba07d28..efb2fc04f6 100644 --- a/arch/arm/src/armv7-a/arm_cpupause.c +++ b/arch/arm/src/armv7-a/arm_cpupause.c @@ -58,6 +58,7 @@ static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +static volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Functions @@ -136,6 +137,10 @@ int up_cpu_paused(int cpu) spin_unlock(&g_cpu_paused[cpu]); + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + /* Wait for the spinlock to be released. The requesting CPU will release * the spinlock when the CPU is resumed. */ @@ -164,6 +169,7 @@ int up_cpu_paused(int cpu) arm_restorestate(tcb->xcp.regs); spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); return OK; } @@ -320,6 +326,13 @@ int up_cpu_resume(int cpu) !spin_islocked(&g_cpu_paused[cpu])); spin_unlock(&g_cpu_wait[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); + return OK; } diff --git a/arch/arm/src/armv7-r/arm_cpupause.c b/arch/arm/src/armv7-r/arm_cpupause.c index ccd865809e..61a455fc96 100644 --- a/arch/arm/src/armv7-r/arm_cpupause.c +++ b/arch/arm/src/armv7-r/arm_cpupause.c @@ -58,6 +58,7 @@ static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +static volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Functions @@ -136,6 +137,10 @@ int up_cpu_paused(int cpu) spin_unlock(&g_cpu_paused[cpu]); + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + /* Wait for the spinlock to be released. The requesting CPU will release * the spinlock when the CPU is resumed. */ @@ -164,6 +169,7 @@ int up_cpu_paused(int cpu) arm_restorestate(tcb->xcp.regs); spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); return OK; } @@ -320,6 +326,13 @@ int up_cpu_resume(int cpu) !spin_islocked(&g_cpu_paused[cpu])); spin_unlock(&g_cpu_wait[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); + return OK; } diff --git a/arch/arm/src/cxd56xx/cxd56_cpupause.c b/arch/arm/src/cxd56xx/cxd56_cpupause.c index e634b98850..c69f8035b8 100644 --- a/arch/arm/src/cxd56xx/cxd56_cpupause.c +++ b/arch/arm/src/cxd56xx/cxd56_cpupause.c @@ -72,6 +72,7 @@ static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +static volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; static volatile int g_irq_to_handle[CONFIG_SMP_NCPUS][2]; @@ -222,6 +223,11 @@ int up_cpu_paused(int cpu) /* Wait for the spinlock to be released */ spin_unlock(&g_cpu_paused[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + spin_lock(&g_cpu_wait[cpu]); /* Restore the exception context of the tcb at the (new) head of the @@ -246,6 +252,7 @@ int up_cpu_paused(int cpu) arm_restorestate(tcb->xcp.regs); spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); return OK; } @@ -418,6 +425,12 @@ int up_cpu_resume(int cpu) !spin_islocked(&g_cpu_paused[cpu])); spin_unlock(&g_cpu_wait[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); return OK; } @@ -463,6 +476,12 @@ void up_send_irqreq(int idx, int irq, int cpu) /* Finally unlock the spinlock to proceed the handler */ spin_unlock(&g_cpu_wait[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); } #endif /* CONFIG_SMP */ diff --git a/arch/arm/src/lc823450/lc823450_cpupause.c b/arch/arm/src/lc823450/lc823450_cpupause.c index 0f311cd0af..13116367d2 100644 --- a/arch/arm/src/lc823450/lc823450_cpupause.c +++ b/arch/arm/src/lc823450/lc823450_cpupause.c @@ -68,6 +68,7 @@ volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Functions @@ -143,6 +144,11 @@ int up_cpu_paused(int cpu) /* Wait for the spinlock to be released */ spin_unlock(&g_cpu_paused[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + spin_lock(&g_cpu_wait[cpu]); /* Restore the exception context of the tcb at the (new) head of the @@ -169,6 +175,8 @@ int up_cpu_paused(int cpu) spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); + return OK; } @@ -343,5 +351,11 @@ int up_cpu_resume(int cpu) spin_unlock(&g_cpu_wait[cpu]); + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); + return 0; } diff --git a/arch/arm/src/rp2040/rp2040_cpupause.c b/arch/arm/src/rp2040/rp2040_cpupause.c index 78059a8486..1f573016c0 100644 --- a/arch/arm/src/rp2040/rp2040_cpupause.c +++ b/arch/arm/src/rp2040/rp2040_cpupause.c @@ -70,6 +70,7 @@ static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +static volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; /**************************************************************************** * Name: rp2040_handle_irqreq @@ -183,6 +184,11 @@ int up_cpu_paused(int cpu) /* Wait for the spinlock to be released */ spin_unlock(&g_cpu_paused[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + spin_lock(&g_cpu_wait[cpu]); /* Restore the exception context of the tcb at the (new) head of the @@ -207,6 +213,7 @@ int up_cpu_paused(int cpu) arm_restorestate(tcb->xcp.regs); spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); return OK; } @@ -393,6 +400,12 @@ int up_cpu_resume(int cpu) !spin_islocked(&g_cpu_paused[cpu])); spin_unlock(&g_cpu_wait[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); return 0; } @@ -432,6 +445,12 @@ void rp2040_send_irqreq(int irqreq) /* Finally unlock the spinlock to proceed the handler */ spin_unlock(&g_cpu_wait[0]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[0]); + + spin_unlock(&g_cpu_resumed[0]); } #endif /* CONFIG_SMP */ diff --git a/arch/arm/src/sam34/sam4cm_cpupause.c b/arch/arm/src/sam34/sam4cm_cpupause.c index d25444f984..48b7944abb 100644 --- a/arch/arm/src/sam34/sam4cm_cpupause.c +++ b/arch/arm/src/sam34/sam4cm_cpupause.c @@ -70,6 +70,7 @@ static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +static volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Functions @@ -145,6 +146,11 @@ int up_cpu_paused(int cpu) /* Wait for the spinlock to be released */ spin_unlock(&g_cpu_paused[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + spin_lock(&g_cpu_wait[cpu]); /* Restore the exception context of the tcb at the (new) head of the @@ -169,6 +175,7 @@ int up_cpu_paused(int cpu) arm_restorestate(tcb->xcp.regs); spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); return OK; } @@ -333,6 +340,13 @@ int up_cpu_resume(int cpu) !spin_islocked(&g_cpu_paused[cpu])); spin_unlock(&g_cpu_wait[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); + return OK; } diff --git a/arch/risc-v/src/common/riscv_cpupause.c b/arch/risc-v/src/common/riscv_cpupause.c index b4c9446819..7d30dc5543 100644 --- a/arch/risc-v/src/common/riscv_cpupause.c +++ b/arch/risc-v/src/common/riscv_cpupause.c @@ -58,6 +58,7 @@ volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Functions @@ -133,6 +134,11 @@ int up_cpu_paused(int cpu) /* Wait for the spinlock to be released */ spin_unlock(&g_cpu_paused[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + spin_lock(&g_cpu_wait[cpu]); /* Restore the exception context of the tcb at the (new) head of the @@ -158,6 +164,7 @@ int up_cpu_paused(int cpu) riscv_restorestate(tcb->xcp.regs); spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); return OK; } @@ -317,5 +324,11 @@ int up_cpu_resume(int cpu) spin_unlock(&g_cpu_wait[cpu]); + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); + return 0; } diff --git a/arch/sim/src/sim/sim_smpsignal.c b/arch/sim/src/sim/sim_smpsignal.c index c7ee9ba4f4..4246dd5fd5 100644 --- a/arch/sim/src/sim/sim_smpsignal.c +++ b/arch/sim/src/sim/sim_smpsignal.c @@ -49,6 +49,7 @@ static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +static volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; /**************************************************************************** * Private Functions @@ -176,6 +177,11 @@ int up_cpu_paused(int cpu) /* Wait for the spinlock to be released */ spin_unlock(&g_cpu_paused[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + spin_lock(&g_cpu_wait[cpu]); /* Restore the exception context of the tcb at the (new) head of the @@ -209,6 +215,7 @@ int up_cpu_paused(int cpu) sim_restorestate(tcb->xcp.regs); spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); return OK; } @@ -394,5 +401,12 @@ int up_cpu_resume(int cpu) !spin_islocked(&g_cpu_paused[cpu])); spin_unlock(&g_cpu_wait[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); + return OK; } diff --git a/arch/sparc/src/s698pm/s698pm_cpupause.c b/arch/sparc/src/s698pm/s698pm_cpupause.c index dd37250737..b9480d1414 100644 --- a/arch/sparc/src/s698pm/s698pm_cpupause.c +++ b/arch/sparc/src/s698pm/s698pm_cpupause.c @@ -58,6 +58,7 @@ volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +volatile spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Functions @@ -133,6 +134,11 @@ int up_cpu_paused(int cpu) /* Wait for the spinlock to be released */ spin_unlock(&g_cpu_paused[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + spin_lock(&g_cpu_wait[cpu]); /* Restore the exception context of the tcb at the (new) head of the @@ -158,6 +164,7 @@ int up_cpu_paused(int cpu) sparc_restorestate(tcb->xcp.regs); spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); return OK; } @@ -320,5 +327,11 @@ int up_cpu_resume(int cpu) spin_unlock(&g_cpu_wait[cpu]); + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); + return 0; } diff --git a/arch/xtensa/src/common/xtensa_cpupause.c b/arch/xtensa/src/common/xtensa_cpupause.c index 1f33cdf5bd..3a87df0317 100644 --- a/arch/xtensa/src/common/xtensa_cpupause.c +++ b/arch/xtensa/src/common/xtensa_cpupause.c @@ -43,6 +43,7 @@ static spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS]; static spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS]; +static spinlock_t g_cpu_resumed[CONFIG_SMP_NCPUS]; /**************************************************************************** * Public Functions @@ -118,6 +119,11 @@ int up_cpu_paused(int cpu) /* Wait for the spinlock to be released */ spin_unlock(&g_cpu_paused[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + spin_lock(&g_cpu_wait[cpu]); /* Restore the exception context of the tcb at the (new) head of the @@ -143,6 +149,8 @@ int up_cpu_paused(int cpu) xtensa_restorestate(tcb->xcp.regs); spin_unlock(&g_cpu_wait[cpu]); + spin_unlock(&g_cpu_resumed[cpu]); + return OK; } @@ -307,6 +315,13 @@ int up_cpu_resume(int cpu) !spin_islocked(&g_cpu_paused[cpu])); spin_unlock(&g_cpu_wait[cpu]); + + /* Ensure the CPU has been resumed to avoid causing a deadlock */ + + spin_lock(&g_cpu_resumed[cpu]); + + spin_unlock(&g_cpu_resumed[cpu]); + return OK; }