You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ma...@apache.org on 2023/05/23 06:48:42 UTC

[nuttx] branch master updated: arch/all: in smp pthread_cancel occasionally deadlock except for arm64

This is an automated email from the ASF dual-hosted git repository.

masayuki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 35b597ec2c arch/all: in smp pthread_cancel occasionally deadlock except for arm64
35b597ec2c is described below

commit 35b597ec2c0154ca675d2cd73f969c717aa3d739
Author: hujun5 <hu...@xiaomi.com>
AuthorDate: Thu May 11 12:27:13 2023 +0800

    arch/all: in smp pthread_cancel occasionally deadlock except for arm64
    
    please reference the issue here for more information:
    https://github.com/apache/nuttx/pull/9065
    
    Signed-off-by: hujun5 <hu...@xiaomi.com>
---
 arch/arm/src/armv7-a/arm_cpupause.c       | 13 +++++++++++++
 arch/arm/src/armv7-r/arm_cpupause.c       | 13 +++++++++++++
 arch/arm/src/cxd56xx/cxd56_cpupause.c     | 19 +++++++++++++++++++
 arch/arm/src/lc823450/lc823450_cpupause.c | 14 ++++++++++++++
 arch/arm/src/rp2040/rp2040_cpupause.c     | 19 +++++++++++++++++++
 arch/arm/src/sam34/sam4cm_cpupause.c      | 14 ++++++++++++++
 arch/risc-v/src/common/riscv_cpupause.c   | 13 +++++++++++++
 arch/sim/src/sim/sim_smpsignal.c          | 14 ++++++++++++++
 arch/sparc/src/s698pm/s698pm_cpupause.c   | 13 +++++++++++++
 arch/xtensa/src/common/xtensa_cpupause.c  | 15 +++++++++++++++
 10 files changed, 147 insertions(+)

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;
 }