From 59e9f84ee6ef1e02746cb638ce3904e855cf3e2c Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 2 Oct 2025 14:18:01 -0700 Subject: [PATCH 1/2] soc: intel_adsp/ace: allows more spin relax loop per CPU This allows adding the CPU ID to the number of NOPs in the custom arch_spin_relax(). With the same number of NOPs for all CPUs, it is possible to have them all doing RCW transactions at the same time over and over again if they enter and exit the spin relax loop at the same time. This behavior has been observed when doing lots of context switching, like in the SMP switching stress test. So adds a new kconfig to fine tune the relax loop behavior if needed. The new kconfig allows adding the CPU ID to the number of NOPs which will add some minimal offsetting to workaround the above mentioned situation. Signed-off-by: Daniel Leung --- soc/intel/intel_adsp/ace/Kconfig | 9 +++++++++ soc/intel/intel_adsp/ace/spin_relax.c | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/soc/intel/intel_adsp/ace/Kconfig b/soc/intel/intel_adsp/ace/Kconfig index cdd2749915d3b..a7e225923aa4e 100644 --- a/soc/intel/intel_adsp/ace/Kconfig +++ b/soc/intel/intel_adsp/ace/Kconfig @@ -53,3 +53,12 @@ config SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS help Specify the number of NOPs in Intel Audio DSP specific arch_spin_relax(). + +config SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID + bool "Add CPU ID to offset NOPs" + depends on SOC_SERIES_INTEL_ADSP_ACE_CUSTOM_MORE_SPIN_RELAX_NOPS + help + Add CPU ID to the number of NOPs in arch_spin_relax(). + This is to add some variations to the loop for each CPU to + further avoid them hitting the RCW transactions at the same + time. diff --git a/soc/intel/intel_adsp/ace/spin_relax.c b/soc/intel/intel_adsp/ace/spin_relax.c index 073deb5a6d07d..0abf94398db1b 100644 --- a/soc/intel/intel_adsp/ace/spin_relax.c +++ b/soc/intel/intel_adsp/ace/spin_relax.c @@ -9,13 +9,20 @@ #include #include +#include + #ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS void arch_spin_relax(void) { register uint32_t remaining = CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS; +#if defined(CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID) + remaining += arch_proc_id(); +#endif /* CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID */ + while (remaining > 0) { -#if (CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS % 4) == 0 +#if !defined(CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID) && \ + (CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS % 4) == 0 remaining -= 4; /* From bcc3c19ec14b38715022e76e1dc498fb182efffa Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 3 Oct 2025 10:11:30 -0700 Subject: [PATCH 2/2] tests: kernel/smp: intel_adsp needs more relaxing NOPs It has been observed that, during the switching stress test, the context switching becomes very slow due to enough CPUs doing RCW transaction on hardware bus (e.g. spin locks). Since the number of NOPs are the same for all CPUs, they are simply entering and exiting the relax loop at the same time, and hitting the bus with RCW transactions at the same time. Not exactly a deadlock but it slows down the execution enough to result in the test timing out. The SoC layer has added an option to offset the number of NOPs per CPU by adding the CPU to the number of NOPs. So enabling it for the Intel ADSP boards to workaround the above mentioned issue. I haven't encountered another slowdown after turning on this option. So hopefully this lowers the probability of that happening such that a simple retry can pass the test. Signed-off-by: Daniel Leung --- tests/kernel/smp/boards/intel_adsp_ace15_mtpm.conf | 3 +++ tests/kernel/smp/boards/intel_adsp_ace20_lnl.conf | 3 +++ tests/kernel/smp/boards/intel_adsp_ace30_ptl.conf | 3 +++ tests/kernel/smp/boards/intel_adsp_ace40_nvl.conf | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 tests/kernel/smp/boards/intel_adsp_ace15_mtpm.conf create mode 100644 tests/kernel/smp/boards/intel_adsp_ace20_lnl.conf create mode 100644 tests/kernel/smp/boards/intel_adsp_ace30_ptl.conf create mode 100644 tests/kernel/smp/boards/intel_adsp_ace40_nvl.conf diff --git a/tests/kernel/smp/boards/intel_adsp_ace15_mtpm.conf b/tests/kernel/smp/boards/intel_adsp_ace15_mtpm.conf new file mode 100644 index 0000000000000..3db4d23770ee0 --- /dev/null +++ b/tests/kernel/smp/boards/intel_adsp_ace15_mtpm.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID=y diff --git a/tests/kernel/smp/boards/intel_adsp_ace20_lnl.conf b/tests/kernel/smp/boards/intel_adsp_ace20_lnl.conf new file mode 100644 index 0000000000000..3db4d23770ee0 --- /dev/null +++ b/tests/kernel/smp/boards/intel_adsp_ace20_lnl.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID=y diff --git a/tests/kernel/smp/boards/intel_adsp_ace30_ptl.conf b/tests/kernel/smp/boards/intel_adsp_ace30_ptl.conf new file mode 100644 index 0000000000000..3db4d23770ee0 --- /dev/null +++ b/tests/kernel/smp/boards/intel_adsp_ace30_ptl.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID=y diff --git a/tests/kernel/smp/boards/intel_adsp_ace40_nvl.conf b/tests/kernel/smp/boards/intel_adsp_ace40_nvl.conf new file mode 100644 index 0000000000000..3db4d23770ee0 --- /dev/null +++ b/tests/kernel/smp/boards/intel_adsp_ace40_nvl.conf @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS_ADD_CPU_ID=y