[PATCH 1/2] ARM: Add per-cpu variable holding cpu number

Keith Packard keithp at keithp.com
Thu Sep 2 08:54:27 PDT 2021


To help move thread_info into task_struct, stop using the cpu number
contained in the thread_info block in C code and use a per-cpu
variable instead. This value will be initialized long before the
task_struct cpu value for the various idle threads are set, which
avoids ordering issues during CPU startup.

Signed-off-by: Keith Packard <keithpac at amazon.com>
---
 arch/arm/include/asm/smp.h |  5 ++++-
 arch/arm/kernel/smp.c      | 14 ++++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 5d508f5d56c4..3aca2c2089bc 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -15,7 +15,10 @@
 # error "<asm/smp.h> included in non-SMP build"
 #endif
 
-#define raw_smp_processor_id() (current_thread_info()->cpu)
+#define raw_smp_processor_id() this_cpu_read(cpu_number)
+#define __smp_processor_id() __this_cpu_read(cpu_number)
+
+DECLARE_PER_CPU_READ_MOSTLY(unsigned int, cpu_number);
 
 struct seq_file;
 
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 74679240a9d8..0457e25109c6 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -51,6 +51,9 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/ipi.h>
 
+DEFINE_PER_CPU_READ_MOSTLY(unsigned int, cpu_number);
+EXPORT_PER_CPU_SYMBOL(cpu_number);
+
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
  * so we need some other way of telling a new secondary core
@@ -495,6 +498,7 @@ void __init smp_prepare_boot_cpu(void)
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
 	unsigned int ncores = num_possible_cpus();
+	unsigned int cpu;
 
 	init_cpu_topology();
 
@@ -505,6 +509,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 	 */
 	if (max_cpus > ncores)
 		max_cpus = ncores;
+
+	/*
+	 * Initialize the cpu_number value for each cpu before we
+	 * start it. This ensures that the value is valid during cpu
+	 * initialization, even before the idle task_struct cpu member
+	 * is set
+	 */
+	for_each_possible_cpu(cpu)
+		per_cpu(cpu_number, cpu) = cpu;
+
 	if (ncores > 1 && max_cpus) {
 		/*
 		 * Initialise the present map, which describes the set of CPUs
-- 
2.33.0




More information about the linux-arm-kernel mailing list