x86: unify x86_32 and 64 NUMA init paths, take#4
Subsystems (4)
PATCH 1/1 x86: unify x86_32 and 64 NUMA init paths, take#4
Hello,
This is the fourth take of unify-x86_32-and-64-NUMA-init-paths patchset.
The only change from the last take[L] is that it's now based on tip/x86/numa. Unfortunately, some of the collisions weren't trivial and led to some ugliness.
Commit c1c3443c ("x86, numa: Fake node-to-cpumask for NUMA emulation") introduced hard dependency on x86_64 into numa_add/remove_cpu() when CONFIG_NUMA_EMU is enabled. 0015 has been updated so that the 32/64 bit common versions used when !CONFIG_NUMA_EMU are in numa.c while CONFIG_NUMA_EMU variants are in numa_64.c.
This is ugly but still better than before. IIUC, Shaohui's patchsets is going to unify NUMA emulation across 32 and 64bit, which should remove the above ugliness. I haven't looked through the patchset yet but after skimming through the current NUMA_EMU code, here are some of my thoughts, FWIW.
* There's no reason for different NUMA config methods to construct different data structures. They all, including 32bit, can build a single set of data structures.
* Then, unification of NUMA_EMU would naturally follow. There's no reason to think about whether the underlying NUMA and proximity information is provided by ACPI, AMD or whatever. It just needs to manipulate the processed data.
Let's _please_ head that way instead of adding more gluing codes and hacks everywhere. It would be a bit more churn but I don't think there's any other sustainable way.
This patchset contains the following sixteen patches.
0001-x86-Kill-unused-static-boot_cpu_logical_apicid-in-sm.patch 0002-x86-Rename-x86_32-MAX_APICID-to-MAX_LOCAL_APIC.patch 0003-x86-Make-default_send_IPI_mask_sequence-allbutself_l.patch 0004-x86-Replace-cpu_2_logical_apicid-with-early-percpu-v.patch 0005-x86-Always-use-x86_cpu_to_logical_apicid-for-cpu-log.patch 0006-x86-Kill-apic-cpu_to_logical_apicid.patch 0007-x86-Add-apic-x86_32_early_logical_apicid.patch 0008-x86-Implement-the-default-x86_32_early_logical_apici.patch 0009-x86-Implement-x86_32_early_logical_apicid-for-bigsmp.patch 0010-x86-Implement-x86_32_early_logical_apicid-for-summit.patch 0011-x86-Implement-x86_32_early_logical_apicid-for-numaq_.patch 0012-x86-Replace-apic-apicid_to_node-with-x86_32_numa_cpu.patch 0013-x86-Unify-cpu-apicid-NUMA-node-mapping-between-32-an.patch 0014-x86-Unify-CPU-NUMA-node-mapping-between-32-and-64bit.patch 0015-x86-Unify-node_to_cpumask_map-handling-between-32-an.patch 0016-x86-Unify-NUMA-initialization-between-32-and-64bit.patch
It's based on top of the current tip/x86/numa (d50e8fc7) and available in the following git branch.
git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc.git unify-numa
Diffstat follows.
arch/x86/Kconfig | 2 arch/x86/include/asm/apic.h | 36 +++--- arch/x86/include/asm/apicdef.h | 1 arch/x86/include/asm/ipi.h | 8 - arch/x86/include/asm/mpspec.h | 3 arch/x86/include/asm/numa.h | 45 +++++++ arch/x86/include/asm/numa_32.h | 7 + arch/x86/include/asm/numa_64.h | 16 -- arch/x86/include/asm/smp.h | 3 arch/x86/include/asm/topology.h | 17 -- arch/x86/kernel/acpi/boot.c | 8 - arch/x86/kernel/apic/apic.c | 39 ++++++ arch/x86/kernel/apic/apic_flat_64.c | 4 arch/x86/kernel/apic/apic_noop.c | 26 ++-- arch/x86/kernel/apic/bigsmp_32.c | 34 ++--- arch/x86/kernel/apic/es7000_32.c | 35 ++---- arch/x86/kernel/apic/ipi.c | 12 +- arch/x86/kernel/apic/numaq_32.c | 21 ++- arch/x86/kernel/apic/probe_32.c | 10 + arch/x86/kernel/apic/summit_32.c | 47 ++------ arch/x86/kernel/apic/x2apic_cluster.c | 2 arch/x86/kernel/apic/x2apic_phys.c | 2 arch/x86/kernel/apic/x2apic_uv_x.c | 2 arch/x86/kernel/cpu/amd.c | 51 +++++--- arch/x86/kernel/cpu/common.c | 2 arch/x86/kernel/cpu/intel.c | 5 arch/x86/kernel/setup.c | 2 arch/x86/kernel/setup_percpu.c | 11 + arch/x86/kernel/smpboot.c | 68 ----------- arch/x86/mm/amdtopology_64.c | 4 arch/x86/mm/numa.c | 197 +++++++++++++++++++++++++++++++++- arch/x86/mm/numa_32.c | 7 + arch/x86/mm/numa_64.c | 192 +++------------------------------ arch/x86/mm/srat_32.c | 6 - arch/x86/mm/srat_64.c | 12 +- 35 files changed, 484 insertions(+), 453 deletions(-)
--
tejun
PATCH 1/16 x86: Kill unused static boot_cpu_logical_apicid in smpboot.c
--- arch/x86/kernel/smpboot.c | 6 +----- 1 files changed, 1 insertions(+), 5 deletions(-)
arch/x86/kernel/smpboot.c +1 -5
@@ -165,8 +165,6 @@ static void unmap_cpu_to_node(int cpu)#endif #ifdef CONFIG_X86_32 -static int boot_cpu_logical_apicid; -u8 cpu_2_logical_apicid[NR_CPUS ]__read_mostly = { [0 ...NR_CPUS -1 ] =BAD_APICID };
@@ -1101,9 +1099,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)* Setup boot CPU information */ smp_store_cpu_info (0 );/* Final full version of the data */ -#ifdef CONFIG_X86_32 - boot_cpu_logical_apicid =logical_smp_processor_id (); -#endif +current_thread_info ()->cpu =0 ;/* needed? */ for_each_possible_cpu (i) {zalloc_cpumask_var (&per_cpu (cpu_sibling_map, i),GFP_KERNEL );
Signature · 1 line
1.7.1
Re: [PATCH 01/16] x86: Kill unused static boot_cpu_logical_apicid in smpboot.c
Quoted 2 lines · Tejun Heo
Signed-off-by Tejun Heo <[email protected]>Reviewed-by Pekka Enberg <[email protected]>
PATCH 2/16 x86: Rename x86_32 MAX_APICID to MAX_LOCAL_APIC
In reply to Tejun HeoReplace x86_32 MAX_APICID in include/asm/mpspec.h with MAX_LOCAL_APIC in include/asm/apicdef.h to make it consistent with x86_64.
--- arch/x86/include/asm/apicdef.h | 1 + arch/x86/include/asm/mpspec.h | 2 -- arch/x86/kernel/smpboot.c | 2 +- arch/x86/mm/srat_32.c | 4 ++-- 4 files changed, 4 insertions(+), 5 deletions(-)
arch/x86/include/asm/apicdef.h +1 -0
@@ -145,6 +145,7 @@#ifdef CONFIG_X86_32 # define MAX_IO_APICS 64 +# define MAX_LOCAL_APIC 256#else # define MAX_IO_APICS 128# define MAX_LOCAL_APIC 32768
arch/x86/include/asm/mpspec.h +0 -2
@@ -32,8 +32,6 @@ extern int mp_bus_id_to_local[MAX_MP_BUSSES];extern int quad_local_to_mp_bus_id [NR_CPUS /4 ][4 ];#endif -#define MAX_APICID 256 -#else /* CONFIG_X86_64: */ #define MAX_MP_BUSSES 256
arch/x86/kernel/smpboot.c +1 -1
@@ -72,7 +72,7 @@#include <asm/i8259.h> #ifdef CONFIG_X86_32 -u8 apicid_2_node[MAX_APICID ]; +u8 apicid_2_node[MAX_LOCAL_APIC ];#endif /* State of each CPU */
arch/x86/mm/srat_32.c +2 -2
@@ -57,7 +57,7 @@ struct node_memory_chunk_s {static struct node_memory_chunk_s __initdata node_memory_chunk[MAXCHUNKS ];static int __initdata num_memory_chunks;/* total number of memory chunks */ -static u8 __initdata apicid_to_pxm[MAX_APICID ]; +static u8 __initdata apicid_to_pxm[MAX_LOCAL_APIC ];int numa_off__initdata ;int acpi_numa__initdata ;
@@ -254,7 +254,7 @@ int __init get_memcfg_from_srat(void)printk (KERN_DEBUG "Number of memory chunks in system = %d\n" , num_memory_chunks); -for (i =0 ; i <MAX_APICID ; i++) +for (i =0 ; i <MAX_LOCAL_APIC ; i++) apicid_2_node[i] =pxm_to_node (apicid_to_pxm[i]);for (j =0 ; j < num_memory_chunks; j++){
Signature · 1 line
1.7.1
Re: [PATCH 02/16] x86: Rename x86_32 MAX_APICID to MAX_LOCAL_APIC
arch/x86/include/asm/apicdef.h line 151
Quoted 12 lines · Tejun Heo
arch/x86/include/asm/apicdef.h +1
-0@@ -145,6 +145,7 @@#ifdef CONFIG_X86_32 # define MAX_IO_APICS 64 +# define MAX_LOCAL_APIC 256#else # define MAX_IO_APICS 128# define MAX_LOCAL_APIC 32768
Looks like Yinghai's 56d91f13 already added this, but didn't convert the rest of the cases that you did. With this hunk removed and an updated changelog:
PATCH 3/16 x86: Make default_send_IPI_mask_sequence/allbutself_logical() 32bit only
In reply to Tejun HeoBoth functions are used only in 32bit. Put them inside CONFIG_X86_32. This is to prepare for logical apicid handling update.
- Cyrill Gorcunov spotted that I forgot to move declarations in ipi.h under CONFIG_X86_32. Fixed.
--- arch/x86/include/asm/ipi.h | 8 ++++---- arch/x86/kernel/apic/ipi.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-)
arch/x86/include/asm/ipi.h +4 -4
@@ -123,10 +123,6 @@ extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask, int vector);extern void default_send_IPI_mask_allbutself_phys (const struct cpumask *mask,int vector); -extern void default_send_IPI_mask_sequence_logical (const struct cpumask *mask, -int vector); -extern void default_send_IPI_mask_allbutself_logical (const struct cpumask *mask, -int vector);/* Avoid include hell */ #define NMI_VECTOR 0x02
@@ -150,6 +146,10 @@ static inline void __default_local_send_IPI_all(int vector) }#ifdef CONFIG_X86_32 +extern void default_send_IPI_mask_sequence_logical (const struct cpumask *mask, +int vector); +extern void default_send_IPI_mask_allbutself_logical (const struct cpumask *mask, +int vector);extern void default_send_IPI_mask_logical (const struct cpumask *mask,int vector);extern void default_send_IPI_allbutself (int vector);
arch/x86/kernel/apic/ipi.c +2 -2
@@ -56,6 +56,8 @@ void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask,local_irq_restore (flags); } +#ifdef CONFIG_X86_32 +void default_send_IPI_mask_sequence_logical (const struct cpumask *mask,int vector) {
@@ -96,8 +98,6 @@ void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask,local_irq_restore (flags); } -#ifdef CONFIG_X86_32 -/* * This is only used on smaller machines. */
Signature · 1 line
1.7.1
Re: [PATCH 03/16] x86: Make default_send_IPI_mask_sequence/allbutself_logical() 32bit only
Quoted 9 lines · Tejun Heo
Both functions are used only in 32bit. Put them inside
CONFIG_X86_32. This is to prepare for logical apicid handling update.- Cyrill Gorcunov spotted that I forgot to move declarations in
ipi.hunderCONFIG_X86_32. Fixed.Signed-off-by Tejun Heo <[email protected]>Reviewed-by Pekka Enberg <[email protected]>Reviewed-by Cyrill Gorcunov <[email protected]>
PATCH 4/16 x86: Replace cpu_2_logical_apicid[] with early percpu variable
In reply to Tejun HeoUnlike x86_64, on x86_32, the mapping from cpu to logical apicid may vary depending on apic in use. cpu_2_logical_apicid[] array is used for this mapping. Replace it with early percpu variable x86_cpu_to_logical_apicid to make it better aligned with other mappings.
--- arch/x86/include/asm/apic.h | 4 ---- arch/x86/include/asm/smp.h | 3 +++ arch/x86/kernel/apic/apic.c | 11 +++++++++++ arch/x86/kernel/apic/es7000_32.c | 2 +- arch/x86/kernel/apic/numaq_32.c | 2 +- arch/x86/kernel/apic/summit_32.c | 4 ++-- arch/x86/kernel/setup_percpu.c | 7 +++++++ arch/x86/kernel/smpboot.c | 7 ++----- 8 files changed, 27 insertions(+), 13 deletions(-)
arch/x86/include/asm/apic.h +0 -4
@@ -595,8 +595,4 @@ extern int default_check_phys_apicid_present(int phys_apicid);#endif /* CONFIG_X86_LOCAL_APIC */ -#ifdef CONFIG_X86_32 -extern u8 cpu_2_logical_apicid[NR_CPUS ]; -#endif -#endif /* _ASM_X86_APIC_H */
arch/x86/include/asm/smp.h +3 -0
@@ -38,6 +38,9 @@ static inline struct cpumask *cpu_core_mask(int cpu)DECLARE_EARLY_PER_CPU (u16, x86_cpu_to_apicid);DECLARE_EARLY_PER_CPU (u16, x86_bios_cpu_apicid); +#if defined(CONFIG_SMP ) && defined(CONFIG_X86_32 ) +DECLARE_EARLY_PER_CPU (int, x86_cpu_to_logical_apicid); +#endif /* Static state in head.S used to set up a CPU */ extern struct {
arch/x86/kernel/apic/apic.c +11 -0
@@ -79,6 +79,17 @@ EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);EXPORT_EARLY_PER_CPU_SYMBOL (x86_bios_cpu_apicid);#ifdef CONFIG_X86_32 + +#ifdef CONFIG_SMP +/* +* On x86_32, the mapping between cpu and logical apicid may vary +* depending on apic in use. The following early percpu variable is +* used for the mapping. This is where the behaviors of x86_64 and 32 +* actually diverge. Let's keep it ugly for now. +*/ +DEFINE_EARLY_PER_CPU (int, x86_cpu_to_logical_apicid,BAD_APICID ); +#endif +/* * Knob to control our willingness to enable the local APIC. *
arch/x86/kernel/apic/es7000_32.c +1 -1
@@ -534,7 +534,7 @@ static int es7000_cpu_to_logical_apicid(int cpu)#ifdef CONFIG_SMP if (cpu >= nr_cpu_ids)return BAD_APICID ; -return cpu_2_logical_apicid[cpu]; +return early_per_cpu (x86_cpu_to_logical_apicid, cpu);#else return logical_smp_processor_id ();#endif
arch/x86/kernel/apic/numaq_32.c +1 -1
@@ -377,7 +377,7 @@ static inline int numaq_cpu_to_logical_apicid(int cpu) {if (cpu >= nr_cpu_ids)return BAD_APICID ; -return cpu_2_logical_apicid[cpu]; +return early_per_cpu (x86_cpu_to_logical_apicid, cpu); }/*
arch/x86/kernel/apic/summit_32.c +2 -2
@@ -206,7 +206,7 @@ static void summit_init_apic_ldr(void)/* Create logical APIC IDs by counting CPUs already in cluster. */ for (count =0 , i = nr_cpu_ids; --i >=0 ; ) { - lid = cpu_2_logical_apicid[i]; + lid =early_per_cpu (x86_cpu_to_logical_apicid, i);if (lid !=BAD_APICID &&APIC_CLUSTER (lid) == my_cluster) ++count; }
@@ -247,7 +247,7 @@ static inline int summit_cpu_to_logical_apicid(int cpu)#ifdef CONFIG_SMP if (cpu >= nr_cpu_ids)return BAD_APICID ; -return cpu_2_logical_apicid[cpu]; +return early_per_cpu (x86_cpu_to_logical_apicid, cpu);#else return logical_smp_processor_id ();#endif
arch/x86/kernel/setup_percpu.c +7 -0
@@ -225,6 +225,10 @@ void __init setup_per_cpu_areas(void)per_cpu (x86_bios_cpu_apicid, cpu) =early_per_cpu_map (x86_bios_cpu_apicid, cpu);#endif +#ifdef CONFIG_X86_32 +per_cpu (x86_cpu_to_logical_apicid, cpu) = +early_per_cpu_map (x86_cpu_to_logical_apicid, cpu); +#endif #ifdef CONFIG_X86_64 per_cpu (irq_stack_ptr, cpu) = per_cpu(irq_stack_union.irq_stack, cpu) +
@@ -256,6 +260,9 @@ void __init setup_per_cpu_areas(void)early_per_cpu_ptr (x86_cpu_to_apicid) =NULL ;early_per_cpu_ptr (x86_bios_cpu_apicid) =NULL ;#endif +#ifdef CONFIG_X86_32 +early_per_cpu_ptr (x86_cpu_to_logical_apicid) =NULL ; +#endif #if defined(CONFIG_X86_64 ) && defined(CONFIG_NUMA )early_per_cpu_ptr (x86_cpu_to_node_map) =NULL ;#endif
arch/x86/kernel/smpboot.c +2 -5
@@ -165,9 +165,6 @@ static void unmap_cpu_to_node(int cpu)#endif #ifdef CONFIG_X86_32 -u8 cpu_2_logical_apicid[NR_CPUS ]__read_mostly = - { [0 ...NR_CPUS -1 ] =BAD_APICID }; -static void map_cpu_to_logical_apicid (void ) {int cpu =smp_processor_id ();
@@ -177,13 +174,13 @@ static void map_cpu_to_logical_apicid(void)if (!node_online (node)) node = first_online_node; - cpu_2_logical_apicid[cpu] = apicid; +early_per_cpu (x86_cpu_to_logical_apicid, cpu) = apicid; map_cpu_to_node(cpu, node); }void numa_remove_cpu (int cpu) { - cpu_2_logical_apicid[cpu] =BAD_APICID ; +early_per_cpu (x86_cpu_to_logical_apicid, cpu) =BAD_APICID ;unmap_cpu_to_node (cpu); }#else
Signature · 1 line
1.7.1
Re: [PATCH 04/16] x86: Replace cpu_2_logical_apicid[] with early percpu variable
Quoted 7 lines · Tejun Heo
Unlike
x86_64, onx86_32, the mapping from cpu to logical apicid may vary depending on apic in use. cpu_2_logical_apicid[] array is used for this mapping. Replace it with early percpu variablex86_cpu_to_logical_apicidto make it better aligned with other mappings.Signed-off-by Tejun Heo <[email protected]>
The apicid's are now stored as int's as opposed to u8, even though the max is 256. Is that for extendability or for better alignment? If not, I think it would be better to keep the old type.
Re: [PATCH 04/16] x86: Replace cpu_2_logical_apicid[] with early percpu variable
Quoted 8 lines · David Rientjes
Quoted 6 lines · Tejun Heo
Unlike
x86_64, onx86_32, the mapping from cpu to logical apicid may vary depending on apic in use. cpu_2_logical_apicid[] array is used for this mapping. Replace it with early percpu variablex86_cpu_to_logical_apicidto make it better aligned with other mappings.
Quoted 5 lines
Quoted 1 line
Signed-off-by Tejun Heo <[email protected]>The apicid's are now stored as int's as opposed to u8, even though the max is 256. Is that for extendability or for better alignment? If not, I think it would be better to keep the old type.
I don't know. Yeah, it's x86_32 only so it can be u8 but other IDs are shared with x86_64 and should be int. I think it's less confusing to simply use int. It's not like the extra overhead is gonna be noticeable or anything.
Thanks.
Signature · 1 line
tejun
PATCH 5/16 x86: Always use x86_cpu_to_logical_apicid for cpu -> logical apic id
In reply to Tejun HeoCurrently, cpu -> logical apic id translation is done by apic->cpu_to_logical_apicid() callback which may or may not use x86_cpu_to_logical_apicid. This is unnecessary as it should always equal logical_smp_processor_id() which is known early during CPU bring up.
Initialize x86_cpu_to_logical_apicid after apic->init_apic_ldr() in setup_local_APIC() and always use x86_cpu_to_logical_apicid for cpu -> logical apic id mapping.
--- arch/x86/kernel/apic/apic.c | 8 ++++++++ arch/x86/kernel/apic/ipi.c | 8 ++++---- arch/x86/kernel/smpboot.c | 7 +++---- 3 files changed, 15 insertions(+), 8 deletions(-)
arch/x86/kernel/apic/apic.c +8 -0
@@ -1252,6 +1252,14 @@ void __cpuinit setup_local_APIC(void)*/ apic->init_apic_ldr (); +#ifdef CONFIG_X86_32 +/* +* APIC LDR is initialized. Fetch and store logical_apic_id. +*/ +early_per_cpu (x86_cpu_to_logical_apicid, cpu) = +logical_smp_processor_id (); +#endif +/* * Set Task Priority to 'accept all'. We never change this * later on.
arch/x86/kernel/apic/ipi.c +4 -4
@@ -73,8 +73,8 @@ void default_send_IPI_mask_sequence_logical(const struct cpumask *mask,local_irq_save (flags);for_each_cpu (query_cpu, mask)__default_send_IPI_dest_field ( - apic->cpu_to_logical_apicid (query_cpu), vector, - apic->dest_logical); +early_per_cpu (x86_cpu_to_logical_apicid, query_cpu), + vector, apic->dest_logical);local_irq_restore (flags); }
@@ -92,8 +92,8 @@ void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask,if (query_cpu == this_cpu)continue ;__default_send_IPI_dest_field ( - apic->cpu_to_logical_apicid (query_cpu), vector, - apic->dest_logical); +early_per_cpu (x86_cpu_to_logical_apicid, query_cpu), + vector, apic->dest_logical); }local_irq_restore (flags); }
arch/x86/kernel/smpboot.c +3 -4
@@ -168,19 +168,18 @@ static void unmap_cpu_to_node(int cpu)static void map_cpu_to_logical_apicid (void ) {int cpu =smp_processor_id (); -int apicid =logical_smp_processor_id (); -int node = apic->apicid_to_node (apicid); +int logical_apicid =early_per_cpu (x86_cpu_to_logical_apicid, cpu); +int node; + node = apic->apicid_to_node (logical_apicid);if (!node_online (node)) node = first_online_node; -early_per_cpu (x86_cpu_to_logical_apicid, cpu) = apicid;map_cpu_to_node (cpu, node); }void numa_remove_cpu (int cpu) { -early_per_cpu (x86_cpu_to_logical_apicid, cpu) =BAD_APICID ;unmap_cpu_to_node (cpu); }#else
Signature · 1 line
1.7.1
Re: [PATCH 05/16] x86: Always use x86_cpu_to_logical_apicid for cpu -> logical apic id
Quoted 9 lines · Tejun Heo
arch/x86/kernel/apic/apic.c +1
-0@@ -1252,6 +1252,14 @@ void __cpuinit setup_local_APIC(void)*/ apic->init_apic_ldr (); +#ifdef CONFIG_X86_32
arch/x86/kernel/apic/apic.c void __cpuinit setup_local_APIC(void) · line 1265
Quoted 10 lines
arch/x86/kernel/apic/apic.c +7
-0+/* +* APIC LDR is initialized. Fetch and store logical_apic_id. +*/ +early_per_cpu (x86_cpu_to_logical_apicid, cpu) = +logical_smp_processor_id (); +#endif +/* * Set Task Priority to 'accept all'. We never change this * later on.
You can remove the initialization of x86_cpu_to_logical_apicid in the ->init_apic_ldr() callback in x2apic_cluster.c now too?
[snip]
Quoted 17 lines
arch/x86/kernel/smpboot.c +3
-2@@ -168,19 +168,18 @@ static void unmap_cpu_to_node(int cpu)static void map_cpu_to_logical_apicid (void ) {int cpu =smp_processor_id (); -int apicid =logical_smp_processor_id (); -int node = apic->apicid_to_node (apicid); +int logical_apicid =early_per_cpu (x86_cpu_to_logical_apicid, cpu); +int node; + node = apic->apicid_to_node (logical_apicid);if (!node_online (node)) node = first_online_node;
arch/x86/kernel/smpboot.c static void unmap_cpu_to_node(int cpu) · line 185
Quoted 10 lines
arch/x86/kernel/smpboot.c +0
-2-early_per_cpu (x86_cpu_to_logical_apicid, cpu) = apicid; map_cpu_to_node(cpu, node); }void numa_remove_cpu (int cpu) { -early_per_cpu (x86_cpu_to_logical_apicid, cpu) =BAD_APICID ;unmap_cpu_to_node (cpu); }#else
I don't see where this is reset to BAD_APICID when numa_remove_cpu() is called when disabling a cpu after the patch.
Re: [PATCH 05/16] x86: Always use x86_cpu_to_logical_apicid for cpu -> logical apic id
Quoted 10 lines · David Rientjes
Quoted 8 lines · Tejun Heo
arch/x86/kernel/apic/apic.c +0
-0@@ -1252,6 +1252,14 @@ void __cpuinit setup_local_APIC(void)*/ apic->init_apic_ldr ();
Quoted 14 lines
arch/x86/kernel/apic/apic.c void __cpuinit setup_local_APIC(void) · line 1265
Quoted 11 lines
arch/x86/kernel/apic/apic.c +8
-0+#ifdef CONFIG_X86_32 +/* +* APIC LDR is initialized. Fetch and store logical_apic_id. +*/ +early_per_cpu (x86_cpu_to_logical_apicid, cpu) = +logical_smp_processor_id (); +#endif +/* * Set Task Priority to 'accept all'. We never change this * later on. You can remove the initialization of
x86_cpu_to_logical_apicidin the ->init_apic_ldr() callback inx2apic_cluster.cnow too?
Believe it or not, that's a different variable. And yeah we probably should clean that up too.
Thanks.
Signature · 1 line
tejun
PATCH 6/16 x86: Kill apic->cpu_to_logical_apicid()
In reply to Tejun HeoAfter the previous patch, apic->cpu_to_logical_apicid() is no longer used. Kill it.
For apic types with custom cpu_to_logical_apicid() which is also used for other purposes, remove the function and modify its users to do the mapping directly.
#ifdef's on CONFIG_SMP in es7000_32 and summit_32 are ignored during conversion as they are not used for UP kernels.
--- arch/x86/include/asm/apic.h | 7 ------- arch/x86/kernel/apic/apic_flat_64.c | 2 -- arch/x86/kernel/apic/apic_noop.c | 6 ------ arch/x86/kernel/apic/bigsmp_32.c | 19 +++++++------------ arch/x86/kernel/apic/es7000_32.c | 18 ++---------------- arch/x86/kernel/apic/numaq_32.c | 8 -------- arch/x86/kernel/apic/probe_32.c | 1 - arch/x86/kernel/apic/summit_32.c | 17 ++--------------- arch/x86/kernel/apic/x2apic_cluster.c | 1 - arch/x86/kernel/apic/x2apic_phys.c | 1 - arch/x86/kernel/apic/x2apic_uv_x.c | 1 - 11 files changed, 11 insertions(+), 70 deletions(-)
arch/x86/include/asm/apic.h +0 -7
@@ -307,7 +307,6 @@ struct apic {void (*setup_apic_routing)(void );int (*multi_timer_check)(int apic,int irq);int (*apicid_to_node)(int logical_apicid); -int (*cpu_to_logical_apicid)(int cpu);int (*cpu_present_to_apicid)(int mps_cpu);void (*apicid_to_cpu_present)(int phys_apicid,physid_mask_t *retmap);void (*setup_portio_remap)(void );
@@ -557,12 +556,6 @@ static inline void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_ma *retmap = *phys_map; } -/* Mapping from cpu number to logical apicid */ -static inline int default_cpu_to_logical_apicid (int cpu) -{ -return 1 << cpu; -} -static inline int __default_cpu_present_to_apicid (int mps_cpu) {if (mps_cpu < nr_cpu_ids &&cpu_present (mps_cpu))
arch/x86/kernel/apic/apic_flat_64.c +0 -2
@@ -186,7 +186,6 @@ struct apic apic_flat = { .setup_apic_routing = NULL, .multi_timer_check = NULL, .apicid_to_node = NULL, - .cpu_to_logical_apicid = NULL, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = NULL, .setup_portio_remap = NULL,
@@ -338,7 +337,6 @@ struct apic apic_physflat = { .setup_apic_routing = NULL, .multi_timer_check = NULL, .apicid_to_node = NULL, - .cpu_to_logical_apicid = NULL, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = NULL, .setup_portio_remap = NULL,
arch/x86/kernel/apic/apic_noop.c +0 -6
@@ -54,11 +54,6 @@ static u64 noop_apic_icr_read(void)return 0 ; } -static int noop_cpu_to_logical_apicid (int cpu) -{ -return 0 ; -} -static int noop_phys_pkg_id (int cpuid_apic,int index_msb) {return 0 ;
@@ -155,7 +150,6 @@ struct apic apic_noop = { .multi_timer_check = NULL, .apicid_to_node = noop_apicid_to_node, - .cpu_to_logical_apicid = noop_cpu_to_logical_apicid, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = physid_set_mask_of_physid,
arch/x86/kernel/apic/bigsmp_32.c +7 -12
@@ -93,14 +93,6 @@ static int bigsmp_cpu_present_to_apicid(int mps_cpu)return BAD_APICID ; } -/* Mapping from cpu number to logical apicid */ -static inline int bigsmp_cpu_to_logical_apicid (int cpu) -{ -if (cpu >= nr_cpu_ids) -return BAD_APICID ; -return cpu_physical_id (cpu); -} -static void bigsmp_ioapic_phys_id_map (physid_mask_t *phys_map,physid_mask_t *retmap) {/* For clustered we don't have a good way to do this yet - hack */
@@ -115,7 +107,11 @@ static int bigsmp_check_phys_apicid_present(int phys_apicid)/* As we are using single CPU as destination, pick only one CPU here */ static unsigned int bigsmp_cpu_mask_to_apicid (const struct cpumask *cpumask) { -return bigsmp_cpu_to_logical_apicid (cpumask_first (cpumask)); +int cpu =cpumask_first (cpumask); + +if (cpu < nr_cpu_ids) +return cpu_physical_id (cpu); +return BAD_APICID ; } static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
@@ -129,9 +125,9 @@ static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,*/ for_each_cpu_and (cpu, cpumask, andmask) {if (cpumask_test_cpu (cpu, cpu_online_mask)) -break ; +return cpu_physical_id (cpu); } -return bigsmp_cpu_to_logical_apicid (cpu); +return BAD_APICID ; }static int bigsmp_phys_pkg_id (int cpuid_apic,int index_msb)
@@ -220,7 +216,6 @@ struct apic apic_bigsmp = { .setup_apic_routing = bigsmp_setup_apic_routing, .multi_timer_check = NULL, .apicid_to_node = bigsmp_apicid_to_node, - .cpu_to_logical_apicid = bigsmp_cpu_to_logical_apicid, .cpu_present_to_apicid = bigsmp_cpu_present_to_apicid, .apicid_to_cpu_present = physid_set_mask_of_physid, .setup_portio_remap = NULL,
arch/x86/kernel/apic/es7000_32.c +2 -16
@@ -528,18 +528,6 @@ static void es7000_apicid_to_cpu_present(int phys_apicid, physid_mask_t *retmap) ++cpu_id; } -/* Mapping from cpu number to logical apicid */ -static int es7000_cpu_to_logical_apicid (int cpu) -{ -#ifdef CONFIG_SMP -if (cpu >= nr_cpu_ids) -return BAD_APICID ; -return early_per_cpu (x86_cpu_to_logical_apicid, cpu); -#else -return logical_smp_processor_id (); -#endif -} -static void es7000_ioapic_phys_id_map (physid_mask_t *phys_map,physid_mask_t *retmap) {/* For clustered we don't have a good way to do this yet - hack */
@@ -561,7 +549,7 @@ static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)* The cpus in the mask must all be on the apic cluster. */ for_each_cpu (cpu, cpumask) { -int new_apicid =es7000_cpu_to_logical_apicid (cpu); +int new_apicid =early_per_cpu (x86_cpu_to_logical_apicid, cpu);if (round &&APIC_CLUSTER (apicid) !=APIC_CLUSTER (new_apicid)) {WARN (1 ,"Not a valid mask!" );
@@ -578,7 +566,7 @@ static unsigned int es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, const struct cpumask *andmask) { - int apicid = es7000_cpu_to_logical_apicid(0); + int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);cpumask_var_t cpumask;if (!alloc_cpumask_var (&cpumask,GFP_ATOMIC ))
@@ -656,7 +644,6 @@ struct apic __refdata apic_es7000_cluster = { .setup_apic_routing = es7000_setup_apic_routing, .multi_timer_check = NULL, .apicid_to_node = es7000_apicid_to_node, - .cpu_to_logical_apicid = es7000_cpu_to_logical_apicid, .cpu_present_to_apicid = es7000_cpu_present_to_apicid, .apicid_to_cpu_present = es7000_apicid_to_cpu_present, .setup_portio_remap = NULL,
@@ -721,7 +708,6 @@ struct apic __refdata apic_es7000 = { .setup_apic_routing = es7000_setup_apic_routing, .multi_timer_check = NULL, .apicid_to_node = es7000_apicid_to_node, - .cpu_to_logical_apicid = es7000_cpu_to_logical_apicid, .cpu_present_to_apicid = es7000_cpu_present_to_apicid, .apicid_to_cpu_present = es7000_apicid_to_cpu_present, .setup_portio_remap = NULL,
arch/x86/kernel/apic/numaq_32.c +0 -8
@@ -373,13 +373,6 @@ static inline void numaq_ioapic_phys_id_map(physid_mask_t *phys_map, physid_maskreturn physids_promote (0xFUL , retmap); } -static inline int numaq_cpu_to_logical_apicid (int cpu) -{ -if (cpu >= nr_cpu_ids) -return BAD_APICID ; -return early_per_cpu (x86_cpu_to_logical_apicid, cpu); -} -/* * Supporting over 60 cpus on NUMA-Q requires a locality-dependent * cpu to APIC ID relation to properly interact with the intelligent
@@ -509,7 +502,6 @@ struct apic __refdata apic_numaq = { .setup_apic_routing = numaq_setup_apic_routing, .multi_timer_check = numaq_multi_timer_check, .apicid_to_node = numaq_apicid_to_node, - .cpu_to_logical_apicid = numaq_cpu_to_logical_apicid, .cpu_present_to_apicid = numaq_cpu_present_to_apicid, .apicid_to_cpu_present = numaq_apicid_to_cpu_present, .setup_portio_remap = numaq_setup_portio_remap,
arch/x86/kernel/apic/probe_32.c +0 -1
@@ -131,7 +131,6 @@ struct apic apic_default = { .setup_apic_routing = setup_apic_flat_routing, .multi_timer_check = NULL, .apicid_to_node = default_apicid_to_node, - .cpu_to_logical_apicid = default_cpu_to_logical_apicid, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = physid_set_mask_of_physid, .setup_portio_remap = NULL,
arch/x86/kernel/apic/summit_32.c +2 -15
@@ -241,18 +241,6 @@ static int summit_apicid_to_node(int logical_apicid)#endif } -/* Mapping from cpu number to logical apicid */ -static inline int summit_cpu_to_logical_apicid (int cpu) -{ -#ifdef CONFIG_SMP -if (cpu >= nr_cpu_ids) -return BAD_APICID ; -return early_per_cpu (x86_cpu_to_logical_apicid, cpu); -#else -return logical_smp_processor_id (); -#endif -} -static int summit_cpu_present_to_apicid (int mps_cpu) {if (mps_cpu < nr_cpu_ids)
@@ -286,7 +274,7 @@ static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask)* The cpus in the mask must all be on the apic cluster. */ for_each_cpu (cpu, cpumask) { -int new_apicid =summit_cpu_to_logical_apicid (cpu); +int new_apicid =early_per_cpu (x86_cpu_to_logical_apicid, cpu);if (round &&APIC_CLUSTER (apicid) !=APIC_CLUSTER (new_apicid)) {printk ("%s: Not a valid mask!\n" , __func__);
@@ -301,7 +289,7 @@ static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask)static unsigned int summit_cpu_mask_to_apicid_and (const struct cpumask *inmask,const struct cpumask *andmask) { -int apicid =summit_cpu_to_logical_apicid (0 ); +int apicid =early_per_cpu (x86_cpu_to_logical_apicid,0 );cpumask_var_t cpumask;if (!alloc_cpumask_var (&cpumask,GFP_ATOMIC ))
@@ -529,7 +517,6 @@ struct apic apic_summit = { .setup_apic_routing = summit_setup_apic_routing, .multi_timer_check = NULL, .apicid_to_node = summit_apicid_to_node, - .cpu_to_logical_apicid = summit_cpu_to_logical_apicid, .cpu_present_to_apicid = summit_cpu_present_to_apicid, .apicid_to_cpu_present = summit_apicid_to_cpu_present, .setup_portio_remap = NULL,
arch/x86/kernel/apic/x2apic_cluster.c +0 -1
@@ -207,7 +207,6 @@ struct apic apic_x2apic_cluster = { .setup_apic_routing = NULL, .multi_timer_check = NULL, .apicid_to_node = NULL, - .cpu_to_logical_apicid = NULL, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = NULL, .setup_portio_remap = NULL,
arch/x86/kernel/apic/x2apic_phys.c +0 -1
@@ -196,7 +196,6 @@ struct apic apic_x2apic_phys = { .setup_apic_routing = NULL, .multi_timer_check = NULL, .apicid_to_node = NULL, - .cpu_to_logical_apicid = NULL, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = NULL, .setup_portio_remap = NULL,
arch/x86/kernel/apic/x2apic_uv_x.c +0 -1
@@ -316,7 +316,6 @@ struct apic __refdata apic_x2apic_uv_x = { .setup_apic_routing = NULL, .multi_timer_check = NULL, .apicid_to_node = NULL, - .cpu_to_logical_apicid = NULL, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = NULL, .setup_portio_remap = NULL,
Signature · 1 line
1.7.1
Re: [PATCH 06/16] x86: Kill apic->cpu_to_logical_apicid()
Quoted 11 lines · Tejun Heo
After the previous patch,
apic->cpu_to_logical_apicid()is no longer used. Kill it.For apic types with custom
cpu_to_logical_apicid()which is also used for other purposes, remove the function and modify its users to do the mapping directly.#ifdef's on
CONFIG_SMPines7000_32andsummit_32are ignored during conversion as they are not used for UP kernels.Signed-off-by Tejun Heo <[email protected]>
PATCH 7/16 x86: Add apic->x86_32_early_logical_apicid()
In reply to Tejun HeoOn x86_32, the mapping between cpu and logical apic ID differs depending on the specific apic implementation in use. The mapping is initialized while bringing up CPUs; however, this makes early inits ignore memory topology.
Add a x86_32 specific apic->x86_32_early_logical_apicid() which is called early during boot to query the mapping. The mapping is later verified against the result of init_apic_ldr(). The method is allowed to return BAD_APICID if it can't be determined early.
noop variant which always returns BAD_APICID is implemented and added to all x86_32 apic implementations.
--- arch/x86/include/asm/apic.h | 19 +++++++++++++++++++ arch/x86/kernel/apic/apic.c | 12 ++++++++++-- arch/x86/kernel/apic/apic_noop.c | 4 ++++ arch/x86/kernel/apic/bigsmp_32.c | 2 ++ arch/x86/kernel/apic/es7000_32.c | 4 ++++ arch/x86/kernel/apic/numaq_32.c | 2 ++ arch/x86/kernel/apic/probe_32.c | 2 ++ arch/x86/kernel/apic/summit_32.c | 2 ++ 8 files changed, 45 insertions(+), 2 deletions(-)
arch/x86/include/asm/apic.h +19 -0
@@ -354,6 +354,20 @@ struct apic {void (*icr_write)(u32 low,u32 high);void (*wait_icr_idle)(void );u32 (*safe_wait_icr_idle)(void); + +#ifdef CONFIG_X86_32 +/* +* Called very early during boot from get_smp_config(). It should +* return the logical apicid. x86_[bios]_cpu_to_apicid is +* initialized before this function is called. +* +* If logical apicid can't be determined that early, the function +* may return BAD_APICID. Logical apicid will be configured after +* init_apic_ldr() while bringing up CPUs. Note that NUMA affinity +* won't be applied properly during early boot in this case. +*/ +int (*x86_32_early_logical_apicid)(int cpu); +#endif };/*
@@ -501,6 +515,11 @@ extern struct apic apic_noop;extern struct apic apic_default; +static inline int noop_x86_32_early_logical_apicid (int cpu) +{ +return BAD_APICID ; +} +/* * Set up the logical destination ID. *
arch/x86/kernel/apic/apic.c +10 -2
@@ -1254,8 +1254,13 @@ void __cpuinit setup_local_APIC(void)#ifdef CONFIG_X86_32 /* -* APIC LDR is initialized. Fetch and store logical_apic_id. +* APIC LDR is initialized. If logical_apicid mapping was +* initialized during get_smp_config(), make sure it matches the +* actual value. */ + i =early_per_cpu (x86_cpu_to_logical_apicid, cpu); +WARN_ON (i !=BAD_APICID && i !=logical_smp_processor_id ()); +/* always use the value from LDR */ early_per_cpu (x86_cpu_to_logical_apicid, cpu) =logical_smp_processor_id ();#endif
@@ -1994,7 +1999,10 @@ void __cpuinit generic_processor_info(int apicid, int version)early_per_cpu (x86_cpu_to_apicid, cpu) = apicid;early_per_cpu (x86_bios_cpu_apicid, cpu) = apicid;#endif - +#ifdef CONFIG_X86_32 +early_per_cpu (x86_cpu_to_logical_apicid, cpu) = + apic->x86_32_early_logical_apicid (cpu); +#endif set_cpu_possible (cpu, true);set_cpu_present (cpu, true); }
arch/x86/kernel/apic/apic_noop.c +4 -0
@@ -191,4 +191,8 @@ struct apic apic_noop = { .icr_write = noop_apic_icr_write, .wait_icr_idle = noop_apic_wait_icr_idle, .safe_wait_icr_idle = noop_safe_apic_wait_icr_idle, + +#ifdef CONFIG_X86_32 + .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, +#endif };
arch/x86/kernel/apic/bigsmp_32.c +2 -0
@@ -251,4 +251,6 @@ struct apic apic_bigsmp = { .icr_write = native_apic_icr_write, .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, + + .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, };
arch/x86/kernel/apic/es7000_32.c +4 -0
@@ -682,6 +682,8 @@ struct apic __refdata apic_es7000_cluster = { .icr_write = native_apic_icr_write, .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, + + .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, };struct apic __refdata apic_es7000 = {
@@ -744,4 +746,6 @@ struct apic __refdata apic_es7000 = { .icr_write = native_apic_icr_write, .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, + + .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, };
arch/x86/kernel/apic/numaq_32.c +2 -0
@@ -539,4 +539,6 @@ struct apic __refdata apic_numaq = { .icr_write = native_apic_icr_write, .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, + + .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, };
arch/x86/kernel/apic/probe_32.c +2 -0
@@ -166,6 +166,8 @@ struct apic apic_default = { .icr_write = native_apic_icr_write, .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, + + .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, };extern struct apic apic_numaq;
arch/x86/kernel/apic/summit_32.c +2 -0
@@ -552,4 +552,6 @@ struct apic apic_summit = { .icr_write = native_apic_icr_write, .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, + + .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, };
Signature · 1 line
1.7.1
PATCH 8/16 x86: Implement the default x86_32_early_logical_apicid()
In reply to Tejun HeoImplement x86_32_early_logical_apicid() for the default apic flat routing.
--- arch/x86/kernel/apic/probe_32.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-)
arch/x86/kernel/apic/probe_32.c +6 -1
@@ -77,6 +77,11 @@ void __init default_setup_apic_routing(void) apic->setup_apic_routing (); } +static int default_x86_32_early_logical_apicid (int cpu) +{ +return 1 << cpu; +} +static void setup_apic_flat_routing (void ) {#ifdef CONFIG_X86_IO_APIC
@@ -167,7 +172,7 @@ struct apic apic_default = { .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, - .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, + .x86_32_early_logical_apicid = default_x86_32_early_logical_apicid, };extern struct apic apic_numaq;
Signature · 1 line
1.7.1
PATCH 9/16 x86: Implement x86_32_early_logical_apicid() for bigsmp_32
In reply to Tejun Heo--- arch/x86/kernel/apic/bigsmp_32.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-)
arch/x86/kernel/apic/bigsmp_32.c +7 -1
@@ -45,6 +45,12 @@ static unsigned long bigsmp_check_apicid_present(int bit)return 1 ; } +static int bigsmp_early_logical_apicid (int cpu) +{ +/* on bigsmp, logical apicid is the same as physical */ +return early_per_cpu (x86_cpu_to_apicid, cpu); +} +static inline unsigned long calculate_ldr (int cpu) {unsigned long val, id;
@@ -252,5 +258,5 @@ struct apic apic_bigsmp = { .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, - .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, + .x86_32_early_logical_apicid = bigsmp_early_logical_apicid, };
Signature · 1 line
1.7.1
PATCH 10/16 x86: Implement x86_32_early_logical_apicid() for summit_32
In reply to Tejun HeoFactor out logical apic id calculation from summit_init_apic_ldr() and use it for the x86_32_early_logical_apicid() callback.
--- arch/x86/kernel/apic/summit_32.c | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-)
arch/x86/kernel/apic/summit_32.c +12 -5
@@ -194,11 +194,10 @@ static unsigned long summit_check_apicid_present(int bit)return 1 ; } -static void summit_init_apic_ldr (void ) +static int summit_early_logical_apicid (int cpu) { -unsigned long val, id;int count =0 ; -u8 my_id = (u8 )hard_smp_processor_id (); +u8 my_id =early_per_cpu (x86_cpu_to_apicid, cpu);u8 my_cluster =APIC_CLUSTER (my_id);#ifdef CONFIG_SMP u8 lid;
@@ -214,7 +213,15 @@ static void summit_init_apic_ldr(void)/* We only have a 4 wide bitmap in cluster mode. If a deranged * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */ BUG_ON (count >=XAPIC_DEST_CPUS_SHIFT ); - id = my_cluster | (1UL << count); +return my_cluster | (1UL << count); +} + +static void summit_init_apic_ldr (void ) +{ +int cpu =smp_processor_id (); +unsigned long id =early_per_cpu (x86_cpu_to_logical_apicid, cpu); +unsigned long val; +apic_write (APIC_DFR ,SUMMIT_APIC_DFR_VALUE ); val =apic_read (APIC_LDR ) & ~APIC_LDR_MASK ; val |=SET_APIC_LOGICAL_ID (id);
@@ -553,5 +560,5 @@ struct apic apic_summit = { .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, - .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, + .x86_32_early_logical_apicid = summit_early_logical_apicid, };
Signature · 1 line
1.7.1
PATCH 11/16 x86: Implement x86_32_early_logical_apicid() for numaq_32
In reply to Tejun Heo--- arch/x86/kernel/apic/es7000_32.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-)
arch/x86/kernel/apic/es7000_32.c +8 -2
@@ -460,6 +460,12 @@ static unsigned long es7000_check_apicid_present(int bit)return physid_isset (bit, phys_cpu_present_map); } +static int es7000_early_logical_apicid (int cpu) +{ +/* on es7000, logical apicid is the same as physical */ +return early_per_cpu (x86_bios_cpu_apicid, cpu); +} +static unsigned long calculate_ldr (int cpu) {unsigned long id =per_cpu (x86_bios_cpu_apicid, cpu);
@@ -683,7 +689,7 @@ struct apic __refdata apic_es7000_cluster = { .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, - .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, + .x86_32_early_logical_apicid = es7000_early_logical_apicid, };struct apic __refdata apic_es7000 = {
@@ -747,5 +753,5 @@ struct apic __refdata apic_es7000 = { .wait_icr_idle = native_apic_wait_icr_idle, .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, - .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, + .x86_32_early_logical_apicid = es7000_early_logical_apicid, };
Signature · 1 line
1.7.1
PATCH 12/16 x86: Replace apic->apicid_to_node() with ->x86_32_numa_cpu_node()
In reply to Tejun Heoapic->apicid_to_node() is 32bit specific apic operation which determines NUMA node for a CPU. Depending on the APIC implementation, it can be easier to determine NUMA node from either physical or logical apicid. Currently, ->apicid_to_node() takes @logical_apicid and calls hard_smp_processor_id() if the physical apicid is needed.
This prevents NUMA mapping from being queried from a different CPU, which in turn makes it impossible to initialize NUMA mapping before SMP bringup.
This patch replaces apic->apicid_to_node() with ->x86_32_numa_cpu_node() which takes @cpu, from which both logical and physical apicids can easily be determined. While at it, drop duplicate implementations from bigsmp_32 and summit_32, and use the default one.
--- arch/x86/include/asm/apic.h | 6 ++++-- arch/x86/kernel/apic/apic.c | 10 +++++++--- arch/x86/kernel/apic/apic_flat_64.c | 2 -- arch/x86/kernel/apic/apic_noop.c | 16 +++++++++------- arch/x86/kernel/apic/bigsmp_32.c | 7 +------ arch/x86/kernel/apic/es7000_32.c | 7 +++---- arch/x86/kernel/apic/numaq_32.c | 11 ++++++++++- arch/x86/kernel/apic/probe_32.c | 2 +- arch/x86/kernel/apic/summit_32.c | 11 +---------- arch/x86/kernel/apic/x2apic_cluster.c | 1 - arch/x86/kernel/apic/x2apic_phys.c | 1 - arch/x86/kernel/apic/x2apic_uv_x.c | 1 - arch/x86/kernel/smpboot.c | 3 +-- 13 files changed, 37 insertions(+), 41 deletions(-)
arch/x86/include/asm/apic.h +4 -2
@@ -306,7 +306,6 @@ struct apic {void (*setup_apic_routing)(void );int (*multi_timer_check)(int apic,int irq); -int (*apicid_to_node)(int logical_apicid);int (*cpu_present_to_apicid)(int mps_cpu);void (*apicid_to_cpu_present)(int phys_apicid,physid_mask_t *retmap);void (*setup_portio_remap)(void );
@@ -367,6 +366,9 @@ struct apic {* won't be applied properly during early boot in this case. */ int (*x86_32_early_logical_apicid)(int cpu); + +/* determine CPU -> NUMA node mapping */ +int (*x86_32_numa_cpu_node)(int cpu);#endif };
@@ -539,7 +541,7 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) return cpuid_apic >> index_msb; } -extern int default_apicid_to_node (int logical_apicid); +extern int default_x86_32_numa_cpu_node (int cpu);#endif
arch/x86/kernel/apic/apic.c +7 -3
@@ -2023,10 +2023,14 @@ void default_init_apic_ldr(void) }#ifdef CONFIG_X86_32 -int default_apicid_to_node (int logical_apicid) +int default_x86_32_numa_cpu_node (int cpu) { -#ifdef CONFIG_SMP -return apicid_2_node[hard_smp_processor_id ()]; +#ifdef CONFIG_NUMA +int apicid =early_per_cpu (x86_cpu_to_apicid, cpu); + +if (apicid !=BAD_APICID ) +return apicid_2_node[apicid]; +return NUMA_NO_NODE ;#else return 0 ;#endif
arch/x86/kernel/apic/apic_flat_64.c +0 -2
@@ -185,7 +185,6 @@ struct apic apic_flat = { .ioapic_phys_id_map = NULL, .setup_apic_routing = NULL, .multi_timer_check = NULL, - .apicid_to_node = NULL, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = NULL, .setup_portio_remap = NULL,
@@ -336,7 +335,6 @@ struct apic apic_physflat = { .ioapic_phys_id_map = NULL, .setup_apic_routing = NULL, .multi_timer_check = NULL, - .apicid_to_node = NULL, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = NULL, .setup_portio_remap = NULL,
arch/x86/kernel/apic/apic_noop.c +9 -7
@@ -108,12 +108,6 @@ static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask)cpumask_set_cpu (cpu, retmask); } -int noop_apicid_to_node (int logical_apicid) -{ -/* we're always on node 0 */ -return 0 ; -} -static u32 noop_apic_read (u32 reg) {WARN_ON_ONCE ((cpu_has_apic && !disable_apic));
@@ -125,6 +119,14 @@ static void noop_apic_write(u32 reg, u32 v)WARN_ON_ONCE (cpu_has_apic && !disable_apic); } +#ifdef CONFIG_X86_32 +static int noop_x86_32_numa_cpu_node (int cpu) +{ +/* we're always on node 0 */ +return 0 ; +} +#endif +struct apic apic_noop = { .name ="noop" , .probe = noop_probe,
@@ -148,7 +150,6 @@ struct apic apic_noop = { .ioapic_phys_id_map = default_ioapic_phys_id_map, .setup_apic_routing = NULL, .multi_timer_check = NULL, - .apicid_to_node = noop_apicid_to_node, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = physid_set_mask_of_physid,
@@ -194,5 +195,6 @@ struct apic apic_noop = {#ifdef CONFIG_X86_32 .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, + .x86_32_numa_cpu_node = noop_x86_32_numa_cpu_node,#endif };
arch/x86/kernel/apic/bigsmp_32.c +1 -6
@@ -86,11 +86,6 @@ static void bigsmp_setup_apic_routing(void) nr_ioapics); } -static int bigsmp_apicid_to_node (int logical_apicid) -{ -return apicid_2_node[hard_smp_processor_id ()]; -} -static int bigsmp_cpu_present_to_apicid (int mps_cpu) {if (mps_cpu < nr_cpu_ids)
@@ -221,7 +216,6 @@ struct apic apic_bigsmp = { .ioapic_phys_id_map = bigsmp_ioapic_phys_id_map, .setup_apic_routing = bigsmp_setup_apic_routing, .multi_timer_check = NULL, - .apicid_to_node = bigsmp_apicid_to_node, .cpu_present_to_apicid = bigsmp_cpu_present_to_apicid, .apicid_to_cpu_present = physid_set_mask_of_physid, .setup_portio_remap = NULL,
@@ -259,4 +253,5 @@ struct apic apic_bigsmp = { .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, .x86_32_early_logical_apicid = bigsmp_early_logical_apicid, + .x86_32_numa_cpu_node = default_x86_32_numa_cpu_node, };
arch/x86/kernel/apic/es7000_32.c +3 -4
@@ -510,12 +510,11 @@ static void es7000_setup_apic_routing(void) nr_ioapics, cpumask_bits(es7000_target_cpus())[0]); } -static int es7000_apicid_to_node (int logical_apicid) +static int es7000_numa_cpu_node (int cpu) {return 0 ; } -static int es7000_cpu_present_to_apicid (int mps_cpu) {if (!mps_cpu)
@@ -649,7 +648,6 @@ struct apic __refdata apic_es7000_cluster = { .ioapic_phys_id_map = es7000_ioapic_phys_id_map, .setup_apic_routing = es7000_setup_apic_routing, .multi_timer_check = NULL, - .apicid_to_node = es7000_apicid_to_node, .cpu_present_to_apicid = es7000_cpu_present_to_apicid, .apicid_to_cpu_present = es7000_apicid_to_cpu_present, .setup_portio_remap = NULL,
@@ -690,6 +688,7 @@ struct apic __refdata apic_es7000_cluster = { .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, .x86_32_early_logical_apicid = es7000_early_logical_apicid, + .x86_32_numa_cpu_node = es7000_numa_cpu_node, };struct apic __refdata apic_es7000 = {
@@ -715,7 +714,6 @@ struct apic __refdata apic_es7000 = { .ioapic_phys_id_map = es7000_ioapic_phys_id_map, .setup_apic_routing = es7000_setup_apic_routing, .multi_timer_check = NULL, - .apicid_to_node = es7000_apicid_to_node, .cpu_present_to_apicid = es7000_cpu_present_to_apicid, .apicid_to_cpu_present = es7000_apicid_to_cpu_present, .setup_portio_remap = NULL,
@@ -754,4 +752,5 @@ struct apic __refdata apic_es7000 = { .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, .x86_32_early_logical_apicid = es7000_early_logical_apicid, + .x86_32_numa_cpu_node = es7000_numa_cpu_node, };
arch/x86/kernel/apic/numaq_32.c +10 -1
@@ -391,6 +391,15 @@ static inline int numaq_apicid_to_node(int logical_apicid)return logical_apicid >>4 ; } +static int numaq_numa_cpu_node (int cpu) +{ +int logical_apicid =early_per_cpu (x86_cpu_to_logical_apicid, cpu); + +if (logical_apicid !=BAD_APICID ) +return numaq_apicid_to_node (logical_apicid); +return NUMA_NO_NODE ; +} +static void numaq_apicid_to_cpu_present (int logical_apicid,physid_mask_t *retmap) {int node =numaq_apicid_to_node (logical_apicid);
@@ -501,7 +510,6 @@ struct apic __refdata apic_numaq = { .ioapic_phys_id_map = numaq_ioapic_phys_id_map, .setup_apic_routing = numaq_setup_apic_routing, .multi_timer_check = numaq_multi_timer_check, - .apicid_to_node = numaq_apicid_to_node, .cpu_present_to_apicid = numaq_cpu_present_to_apicid, .apicid_to_cpu_present = numaq_apicid_to_cpu_present, .setup_portio_remap = numaq_setup_portio_remap,
@@ -541,4 +549,5 @@ struct apic __refdata apic_numaq = { .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid, + .x86_32_numa_cpu_node = numaq_numa_cpu_node, };
arch/x86/kernel/apic/probe_32.c +1 -1
@@ -135,7 +135,6 @@ struct apic apic_default = { .ioapic_phys_id_map = default_ioapic_phys_id_map, .setup_apic_routing = setup_apic_flat_routing, .multi_timer_check = NULL, - .apicid_to_node = default_apicid_to_node, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = physid_set_mask_of_physid, .setup_portio_remap = NULL,
@@ -173,6 +172,7 @@ struct apic apic_default = { .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, .x86_32_early_logical_apicid = default_x86_32_early_logical_apicid, + .x86_32_numa_cpu_node = default_x86_32_numa_cpu_node, };extern struct apic apic_numaq;
arch/x86/kernel/apic/summit_32.c +1 -10
@@ -239,15 +239,6 @@ static void summit_setup_apic_routing(void) nr_ioapics); } -static int summit_apicid_to_node (int logical_apicid) -{ -#ifdef CONFIG_SMP -return apicid_2_node[hard_smp_processor_id ()]; -#else -return 0 ; -#endif -} -static int summit_cpu_present_to_apicid (int mps_cpu) {if (mps_cpu < nr_cpu_ids)
@@ -523,7 +514,6 @@ struct apic apic_summit = { .ioapic_phys_id_map = summit_ioapic_phys_id_map, .setup_apic_routing = summit_setup_apic_routing, .multi_timer_check = NULL, - .apicid_to_node = summit_apicid_to_node, .cpu_present_to_apicid = summit_cpu_present_to_apicid, .apicid_to_cpu_present = summit_apicid_to_cpu_present, .setup_portio_remap = NULL,
@@ -561,4 +551,5 @@ struct apic apic_summit = { .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, .x86_32_early_logical_apicid = summit_early_logical_apicid, + .x86_32_numa_cpu_node = default_x86_32_numa_cpu_node, };
arch/x86/kernel/apic/x2apic_cluster.c +0 -1
@@ -206,7 +206,6 @@ struct apic apic_x2apic_cluster = { .ioapic_phys_id_map = NULL, .setup_apic_routing = NULL, .multi_timer_check = NULL, - .apicid_to_node = NULL, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = NULL, .setup_portio_remap = NULL,
arch/x86/kernel/apic/x2apic_phys.c +0 -1
@@ -195,7 +195,6 @@ struct apic apic_x2apic_phys = { .ioapic_phys_id_map = NULL, .setup_apic_routing = NULL, .multi_timer_check = NULL, - .apicid_to_node = NULL, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = NULL, .setup_portio_remap = NULL,
arch/x86/kernel/apic/x2apic_uv_x.c +0 -1
@@ -315,7 +315,6 @@ struct apic __refdata apic_x2apic_uv_x = { .ioapic_phys_id_map = NULL, .setup_apic_routing = NULL, .multi_timer_check = NULL, - .apicid_to_node = NULL, .cpu_present_to_apicid = default_cpu_present_to_apicid, .apicid_to_cpu_present = NULL, .setup_portio_remap = NULL,
arch/x86/kernel/smpboot.c +1 -2
@@ -168,10 +168,9 @@ static void unmap_cpu_to_node(int cpu)static void map_cpu_to_logical_apicid (void ) {int cpu =smp_processor_id (); -int logical_apicid =early_per_cpu (x86_cpu_to_logical_apicid, cpu);int node; - node = apic->apicid_to_node (logical_apicid); + node = apic->x86_32_numa_cpu_node (cpu);if (!node_online (node)) node = first_online_node;
Signature · 1 line
1.7.1
PATCH 13/16 x86: Unify cpu/apicid <-> NUMA node mapping between 32 and 64bit
In reply to Tejun HeoThe mapping between cpu/apicid and node is done via apicid_to_node[] on 64bit and apicid_2_node[] + apic->x86_32_numa_cpu_node() on 32bit. This difference makes it difficult to further unify 32 and 64bit NUMA handling.
This patch unifies it by replacing both apicid_to_node[] and apicid_2_node[] with __apicid_to_node[] array, which is accessed by two accessors - set_apicid_to_node() and numa_cpu_node(). On 64bit, numa_cpu_node() always consults __apicid_to_node[] directly while 32bit goes through apic->numa_cpu_node() method to allow apic implementations to override it.
srat_detect_node() for amd cpus contains workaround for broken NUMA configuration which assumes relationship between APIC ID, HT node ID and NUMA topology. Leave it to access __apicid_to_node[] directly as mapping through CPU might result in undesirable behavior change. The comment is reformatted and updated to note the ugliness.
--- arch/x86/include/asm/mpspec.h | 1 - arch/x86/include/asm/numa.h | 28 +++++++++++++++++++++++ arch/x86/include/asm/numa_32.h | 6 +++++ arch/x86/include/asm/numa_64.h | 5 +-- arch/x86/kernel/acpi/boot.c | 3 +- arch/x86/kernel/apic/apic.c | 2 +- arch/x86/kernel/cpu/amd.c | 47 +++++++++++++++++++++++++-------------- arch/x86/kernel/cpu/intel.c | 3 +- arch/x86/kernel/smpboot.c | 6 +---- arch/x86/mm/amdtopology_64.c | 4 +- arch/x86/mm/numa.c | 6 ++++- arch/x86/mm/numa_32.c | 6 +++++ arch/x86/mm/numa_64.c | 26 +++++++++------------ arch/x86/mm/srat_32.c | 2 +- arch/x86/mm/srat_64.c | 12 +++++----- 15 files changed, 101 insertions(+), 56 deletions(-)
arch/x86/include/asm/mpspec.h +0 -1
@@ -24,7 +24,6 @@ extern int pic_mode;#define MAX_IRQ_SOURCES 256extern unsigned int def_to_bigsmp; -extern u8 apicid_2_node[];#ifdef CONFIG_X86_NUMAQ extern int mp_bus_id_to_node[MAX_MP_BUSSES ];
arch/x86/include/asm/numa.h +28 -0
@@ -1,5 +1,33 @@ +#ifndef _ASM_X86_NUMA_H +#define _ASM_X86_NUMA_H + +#include <asm/apicdef.h> + +#ifdef CONFIG_NUMA +/* +* __apicid_to_node[] stores the raw mapping between physical apicid and +* node and is used to initialize cpu_to_node mapping. +* +* The mapping may be overridden by apic->numa_cpu_node() on 32bit and thus +* should be accessed by the accessors - set_apicid_to_node() and +* numa_cpu_node(). +*/ +extern s16 __apicid_to_node[MAX_LOCAL_APIC ]; + +static inline void set_apicid_to_node (int apicid,s16 node) +{ + __apicid_to_node[apicid] = node; +} +#else /* CONFIG_NUMA */ +static inline void set_apicid_to_node (int apicid,s16 node) +{ +} +#endif /* CONFIG_NUMA */ +#ifdef CONFIG_X86_32 # include "numa_32.h" #else # include "numa_64.h" #endif + +#endif /* _ASM_X86_NUMA_H */
arch/x86/include/asm/numa_32.h +6 -0
@@ -4,6 +4,12 @@extern int pxm_to_nid (int pxm);extern void numa_remove_cpu (int cpu); +#ifdef CONFIG_NUMA +extern int __cpuinit numa_cpu_node (int apicid); +#else /* CONFIG_NUMA */ +static inline int numa_cpu_node (int cpu) {return NUMA_NO_NODE ; } +#endif /* CONFIG_NUMA */ +#ifdef CONFIG_HIGHMEM extern void set_highmem_pages_init (void );#else
arch/x86/include/asm/numa_64.h +2 -3
@@ -2,7 +2,6 @@#define _ASM_X86_NUMA_64_H#include <linux/nodemask.h> -#include <asm/apicdef.h> struct bootnode {u64 start;
@@ -17,8 +16,6 @@ extern int compute_hash_shift(struct bootnode *nodes, int numblks,extern void numa_init_array (void );extern int numa_off; -extern s16 apicid_to_node[MAX_LOCAL_APIC ]; -extern unsigned long numa_free_all_bootmem (void );extern void setup_node_bootmem (int nodeid,unsigned long start,unsigned long end);
@@ -32,6 +29,7 @@ extern void setup_node_bootmem(int nodeid, unsigned long start,#define NODE_MIN_SIZE (4*1024*1024)extern void __init init_cpu_to_node (void ); +extern int __cpuinit numa_cpu_node (int cpu);extern void __cpuinit numa_set_node (int cpu,int node);extern void __cpuinit numa_clear_node (int cpu);extern void __cpuinit numa_add_cpu (int cpu);
@@ -43,6 +41,7 @@ extern void __cpuinit numa_remove_cpu(int cpu);#endif /* CONFIG_NUMA_EMU */ #else static inline void init_cpu_to_node (void ) { } +static inline int numa_cpu_node (int cpu) {return NUMA_NO_NODE ; }static inline void numa_set_node (int cpu,int node) { }static inline void numa_clear_node (int cpu) { }static inline void numa_add_cpu (int cpu,int node) { }
arch/x86/kernel/acpi/boot.c +1 -2
@@ -583,11 +583,10 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) nid =acpi_get_node (handle);if (nid ==-1 || !node_online (nid))return ; +set_apicid_to_node (physid, nid);#ifdef CONFIG_X86_64 - apicid_to_node[physid] = nid;numa_set_node (cpu, nid);#else /* CONFIG_X86_32 */ - apicid_2_node[physid] = nid; cpu_to_node_map[cpu] = nid;#endif
arch/x86/kernel/apic/apic.c +1 -1
@@ -2029,7 +2029,7 @@ int default_x86_32_numa_cpu_node(int cpu)int apicid =early_per_cpu (x86_cpu_to_apicid, cpu);if (apicid !=BAD_APICID ) -return apicid_2_node[apicid]; +return __apicid_to_node[apicid];return NUMA_NO_NODE ;#else return 0 ;
arch/x86/kernel/cpu/amd.c +30 -17
73 lines not on this page · raw message
arch/x86/kernel/cpu/intel.c +1 -2
@@ -279,11 +279,10 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)#if defined(CONFIG_NUMA ) && defined(CONFIG_X86_64 )unsigned node;int cpu =smp_processor_id (); -int apicid = cpu_has_apic ?hard_smp_processor_id () : c->apicid;/* Don't do the funky fallback heuristics the AMD version employs for now. */ - node = apicid_to_node[apicid]; + node =numa_cpu_node (cpu);if (node ==NUMA_NO_NODE || !node_online (node)) {/* reuse the value from init_cpu_to_node() */ node =cpu_to_node (cpu);
arch/x86/kernel/smpboot.c +1 -5
@@ -71,10 +71,6 @@#include <asm/smpboot_hooks.h> #include <asm/i8259.h> -#ifdef CONFIG_X86_32 -u8 apicid_2_node[MAX_LOCAL_APIC ]; -#endif -/* State of each CPU */ DEFINE_PER_CPU(int, cpu_state) = { 0 };
@@ -170,7 +166,7 @@ static void map_cpu_to_logical_apicid(void)int cpu =smp_processor_id ();int node; - node = apic->x86_32_numa_cpu_node (cpu); + node =numa_cpu_node (cpu);if (!node_online (node)) node = first_online_node;
arch/x86/mm/amdtopology_64.c +2 -2
@@ -247,7 +247,7 @@ void __init amd_fake_nodes(const struct bootnode *nodes, int nr_nodes)__acpi_map_pxm_to_node (nid, i); #endif } -memcpy (apicid_to_node, fake_apicid_to_node,sizeof (apicid_to_node)); +memcpy (__apicid_to_node, fake_apicid_to_node,sizeof (__apicid_to_node)); }#endif /* CONFIG_NUMA_EMU */
@@ -285,7 +285,7 @@ int __init amd_scan_nodes(void) nodes[i].start >>PAGE_SHIFT , nodes[i].end >> PAGE_SHIFT);for (j = apicid_base; j < cores + apicid_base; j++) - apicid_to_node[(i << bits) + j] = i; +set_apicid_to_node ((i << bits) + j, i);setup_node_bootmem (i, nodes[i].start, nodes[i].end); }
arch/x86/mm/numa.c +5 -1
@@ -4,8 +4,12 @@#include <linux/bootmem.h> /* -* Which logical CPUs are on which nodes +* apicid, cpu, node mappings */ +s16 __apicid_to_node[MAX_LOCAL_APIC ]__cpuinitdata = { + [0 ...MAX_LOCAL_APIC -1 ] =NUMA_NO_NODE +}; +cpumask_var_t node_to_cpumask_map[MAX_NUMNODES ];EXPORT_SYMBOL (node_to_cpumask_map);
arch/x86/mm/numa_32.c +6 -0
@@ -110,6 +110,12 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);static unsigned long kva_start_pfn;static unsigned long kva_pages; + +int __cpuinit numa_cpu_node (int cpu) +{ +return apic->x86_32_numa_cpu_node (cpu); +} +/* * FLAT - support for basic PC memory model with discontig enabled, essentially * a single node with all available processors in it with a flat
arch/x86/mm/numa_64.c +11 -15
@@ -26,10 +26,6 @@ EXPORT_SYMBOL(node_data);struct memnode memnode; -s16 apicid_to_node[MAX_LOCAL_APIC ]__cpuinitdata = { - [0 ...MAX_LOCAL_APIC -1 ] =NUMA_NO_NODE -}; -int numa_off__initdata ;static unsigned long __initdata nodemap_addr;static unsigned long __initdata nodemap_size;
@@ -730,12 +726,8 @@ void __init init_cpu_to_node(void)BUG_ON (cpu_to_apicid ==NULL );for_each_possible_cpu (cpu) { -int node; -u16 apicid = cpu_to_apicid[cpu]; +int node =numa_cpu_node (cpu); -if (apicid ==BAD_APICID ) -continue ; - node = apicid_to_node[apicid];if (node ==NUMA_NO_NODE )continue ;if (!node_online (node))
@@ -745,6 +737,14 @@ void __init init_cpu_to_node(void) }#endif +int __cpuinit numa_cpu_node (int cpu) +{ +int apicid =early_per_cpu (x86_cpu_to_apicid, cpu); + +if (apicid !=BAD_APICID ) +return __apicid_to_node[apicid]; +return NUMA_NO_NODE ; +}void __cpuinit numa_set_node (int cpu,int node) {
@@ -790,13 +790,9 @@ void __cpuinit numa_remove_cpu(int cpu)void __cpuinit numa_add_cpu (int cpu) {unsigned long addr; -u16 apicid; -int physnid; -int nid =NUMA_NO_NODE ; +int physnid, nid; - apicid =early_per_cpu (x86_cpu_to_apicid, cpu); -if (apicid !=BAD_APICID ) - nid = apicid_to_node[apicid]; + nid =numa_cpu_node (cpu);if (nid ==NUMA_NO_NODE ) nid =early_cpu_to_node (cpu);BUG_ON (nid ==NUMA_NO_NODE || !node_online (nid));
arch/x86/mm/srat_32.c +1 -1
@@ -255,7 +255,7 @@ int __init get_memcfg_from_srat(void) num_memory_chunks);for (i =0 ; i <MAX_LOCAL_APIC ; i++) - apicid_2_node[i] =pxm_to_node (apicid_to_pxm[i]); +set_apicid_to_node (i,pxm_to_node (apicid_to_pxm[i]));for (j =0 ; j < num_memory_chunks; j++){struct node_memory_chunk_s * chunk = &node_memory_chunk[j];
arch/x86/mm/srat_64.c +6 -6
@@ -79,7 +79,7 @@ static __init void bad_srat(void)printk (KERN_ERR "SRAT: SRAT not used.\n" ); acpi_numa =-1 ;for (i =0 ; i <MAX_LOCAL_APIC ; i++) - apicid_to_node[i] =NUMA_NO_NODE ; +set_apicid_to_node (i,NUMA_NO_NODE );for (i =0 ; i <MAX_NUMNODES ; i++) { nodes[i].start = nodes[i].end =0 ; nodes_add[i].start = nodes_add[i].end =0 ;
@@ -134,7 +134,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) } apic_id = pa->apic_id; - apicid_to_node[apic_id] = node; +set_apicid_to_node (apic_id, node);node_set (node, cpu_nodes_parsed); acpi_numa =1 ; printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n",
@@ -168,7 +168,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) apic_id = (pa->apic_id <<8 ) | pa->local_sapic_eid; else apic_id = pa->apic_id; - apicid_to_node[apic_id] = node; +set_apicid_to_node (apic_id, node);node_set (node, cpu_nodes_parsed); acpi_numa =1 ; printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n",
@@ -511,7 +511,7 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes)* node, it must now point to the fake node ID. */ for (j =0 ; j <MAX_LOCAL_APIC ; j++) -if (apicid_to_node[j] == nid && +if (__apicid_to_node[j] == nid && fake_apicid_to_node[j] ==NUMA_NO_NODE ) fake_apicid_to_node[j] = i; }
@@ -522,13 +522,13 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes)* value. */ for (i =0 ; i <MAX_LOCAL_APIC ; i++) -if (apicid_to_node[i] !=NUMA_NO_NODE && +if (__apicid_to_node[i] !=NUMA_NO_NODE && fake_apicid_to_node[i] ==NUMA_NO_NODE ) fake_apicid_to_node[i] =0 ;for (i =0 ; i < num_nodes; i++)__acpi_map_pxm_to_node (fake_node_to_pxm_map[i], i); -memcpy (apicid_to_node, fake_apicid_to_node,sizeof (apicid_to_node)); +memcpy (__apicid_to_node, fake_apicid_to_node,sizeof (__apicid_to_node));nodes_clear (nodes_parsed);for (i =0 ; i < num_nodes; i++)
Signature · 1 line
1.7.1
PATCH 14/16 x86: Unify CPU -> NUMA node mapping between 32 and 64bit
In reply to Tejun HeoUnlike 64bit, 32bit has been using its own cpu_to_node_map[] for CPU -> NUMA node mapping. Replace it with early_percpu variable x86_cpu_to_node_map and share the mapping code with 64bit.
* USE_PERCPU_NUMA_NODE_ID is now enabled for 32bit too.
* x86_cpu_to_node_map and numa_set/clear_node() are moved from numa_64 to numa. For now, on 32bit, x86_cpu_to_node_map is initialized with 0 instead of NUMA_NO_NODE. This is to avoid introducing unexpected behavior change and will be updated once init path is unified.
* srat_detect_node() is now enabled for x86_32 too. It calls numa_set_node() and initializes the mapping making explicit cpu_to_node_map[] updates from map/unmap_cpu_to_node() unnecessary.
--- arch/x86/Kconfig | 2 +- arch/x86/include/asm/numa.h | 8 ++++ arch/x86/include/asm/numa_64.h | 4 -- arch/x86/include/asm/topology.h | 17 --------- arch/x86/kernel/acpi/boot.c | 5 --- arch/x86/kernel/cpu/amd.c | 4 +- arch/x86/kernel/cpu/intel.c | 2 +- arch/x86/kernel/setup_percpu.c | 4 +- arch/x86/kernel/smpboot.c | 6 --- arch/x86/mm/numa.c | 72 ++++++++++++++++++++++++++++++++++++++- arch/x86/mm/numa_64.c | 65 ----------------------------------- 11 files changed, 85 insertions(+), 104 deletions(-)
arch/x86/Kconfig +1 -1
@@ -1707,7 +1707,7 @@ config HAVE_ARCH_EARLY_PFN_TO_NID depends on NUMA config USE_PERCPU_NUMA_NODE_ID - def_bool X86_64 + def_bool y depends on NUMA menu "Power management and ACPI options"
arch/x86/include/asm/numa.h +8 -0
@@ -30,4 +30,12 @@ static inline void set_apicid_to_node(int apicid, s16 node)# include "numa_64.h" #endif +#ifdef CONFIG_NUMA +extern void __cpuinit numa_set_node (int cpu,int node); +extern void __cpuinit numa_clear_node (int cpu); +#else /* CONFIG_NUMA */ +static inline void numa_set_node (int cpu,int node) { } +static inline void numa_clear_node (int cpu) { } +#endif /* CONFIG_NUMA */ +#endif /* _ASM_X86_NUMA_H */
arch/x86/include/asm/numa_64.h +0 -4
@@ -30,8 +30,6 @@ extern void setup_node_bootmem(int nodeid, unsigned long start,extern void __init init_cpu_to_node (void );extern int __cpuinit numa_cpu_node (int cpu); -extern void __cpuinit numa_set_node (int cpu,int node); -extern void __cpuinit numa_clear_node (int cpu);extern void __cpuinit numa_add_cpu (int cpu);extern void __cpuinit numa_remove_cpu (int cpu);
@@ -42,8 +40,6 @@ extern void __cpuinit numa_remove_cpu(int cpu);#else static inline void init_cpu_to_node (void ) { }static inline int numa_cpu_node (int cpu) {return NUMA_NO_NODE ; } -static inline void numa_set_node (int cpu,int node) { } -static inline void numa_clear_node (int cpu) { }static inline void numa_add_cpu (int cpu,int node) { }static inline void numa_remove_cpu (int cpu) { }#endif
arch/x86/include/asm/topology.h +0 -17
@@ -47,21 +47,6 @@#include <asm/mpspec.h> -#ifdef CONFIG_X86_32 - -/* Mappings between logical cpu number and node number */ -extern int cpu_to_node_map[]; - -/* Returns the number of the node containing CPU 'cpu' */ -static inline int __cpu_to_node (int cpu) -{ -return cpu_to_node_map[cpu]; -} -#define early_cpu_to_node __cpu_to_node -#define cpu_to_node __cpu_to_node - -#else /* CONFIG_X86_64 */ -/* Mappings between logical cpu number and node number */ DECLARE_EARLY_PER_CPU (int, x86_cpu_to_node_map);
@@ -84,8 +69,6 @@ static inline int early_cpu_to_node(int cpu)#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ -#endif /* CONFIG_X86_64 */ -/* Mappings between node number and cpus on that node. */ extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES ];
arch/x86/kernel/acpi/boot.c +0 -5
@@ -584,12 +584,7 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)if (nid ==-1 || !node_online (nid))return ;set_apicid_to_node (physid, nid); -#ifdef CONFIG_X86_64 numa_set_node (cpu, nid); -#else /* CONFIG_X86_32 */ - cpu_to_node_map[cpu] = nid; -#endif -#endif }
arch/x86/kernel/cpu/amd.c +2 -2
@@ -233,7 +233,7 @@ static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c) }#endif -#if defined(CONFIG_NUMA ) && defined(CONFIG_X86_64 ) +#ifdef CONFIG_NUMA /* * To workaround broken NUMA config. Read the comment in * srat_detect_node().
@@ -338,7 +338,7 @@ EXPORT_SYMBOL_GPL(amd_get_nb_id);static void __cpuinit srat_detect_node (struct cpuinfo_x86 *c) { -#if defined(CONFIG_NUMA ) && defined(CONFIG_X86_64 ) +#ifdef CONFIG_NUMA int cpu =smp_processor_id ();int node;unsigned apicid = c->apicid;
arch/x86/kernel/cpu/intel.c +1 -1
@@ -276,7 +276,7 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)static void __cpuinit srat_detect_node (struct cpuinfo_x86 *c) { -#if defined(CONFIG_NUMA ) && defined(CONFIG_X86_64 ) +#ifdef CONFIG_NUMA unsigned node;int cpu =smp_processor_id ();
arch/x86/kernel/setup_percpu.c +2 -2
@@ -233,6 +233,7 @@ void __init setup_per_cpu_areas(void)per_cpu (irq_stack_ptr, cpu) =per_cpu (irq_stack_union.irq_stack, cpu) +IRQ_STACK_SIZE -64 ; +#endif #ifdef CONFIG_NUMA per_cpu (x86_cpu_to_node_map, cpu) =early_per_cpu_map (x86_cpu_to_node_map, cpu);
@@ -246,7 +247,6 @@ void __init setup_per_cpu_areas(void)*/ set_cpu_numa_node (cpu,early_cpu_to_node (cpu));#endif -#endif /* * Up to this point, the boot CPU has been using .init.data * area. Reload any changed state for the boot CPU.
@@ -263,7 +263,7 @@ void __init setup_per_cpu_areas(void)#ifdef CONFIG_X86_32 early_per_cpu_ptr (x86_cpu_to_logical_apicid) =NULL ;#endif -#if defined(CONFIG_X86_64 ) && defined(CONFIG_NUMA ) +#ifdef CONFIG_NUMA early_per_cpu_ptr (x86_cpu_to_node_map) =NULL ;#endif
arch/x86/kernel/smpboot.c +0 -6
@@ -133,16 +133,11 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);atomic_t init_deasserted;#if defined(CONFIG_NUMA ) && defined(CONFIG_X86_32 ) -/* which node each logical CPU is on */ -int cpu_to_node_map[NR_CPUS ]__read_mostly = { [0 ...NR_CPUS -1 ] =0 }; -EXPORT_SYMBOL (cpu_to_node_map); -/* set up a mapping between cpu and node. */ static void map_cpu_to_node (int cpu,int node) {printk (KERN_INFO "Mapping cpu %d to node %d\n" , cpu, node);cpumask_set_cpu (cpu, node_to_cpumask_map[node]); - cpu_to_node_map[cpu] = node; }/* undo a mapping between cpu and node. */
@@ -153,7 +148,6 @@ static void unmap_cpu_to_node(int cpu)printk (KERN_INFO "Unmapping cpu %d from all nodes\n" , cpu);for (node =0 ; node <MAX_NUMNODES ; node++) cpumask_clear_cpu(cpu, node_to_cpumask_map[node]); - cpu_to_node_map[cpu] = 0; }#else /* !(CONFIG_NUMA && CONFIG_X86_32) */ #define map_cpu_to_node (cpu, node) ({})
arch/x86/mm/numa.c +71 -1
87 lines not on this page · raw message
arch/x86/mm/numa_64.c +0 -65
83 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH 15/16 x86: Unify node_to_cpumask_map handling between 32 and 64bit
In reply to Tejun Heox86_32 has been managing node_to_cpumask_map explicitly from map_cpu_to_node() and friends in a rather ugly way. With previous changes, it's now possible to share the code with 64bit.
* When CONFIG_NUMA_EMU is disabled, numa_add/remove_cpu() are implemented in numa.c and shared by 32 and 64bit. The !NUMA_EMU implementation is taken from numa_64.c right before c1c3443c ("x86,
numa: Fake node-to-cpumask for NUMA emulation"). CONFIG_NUMA_EMU versions still live in numa_64.c.
NUMA_EMU's dependency on 64bit is planned to be removed and the above should go away together.
* identify_cpu() now calls numa_add_cpu() for 32bit too. This makes the explicit mask management from map_cpu_to_node() unnecessary.
* The whole x86_32 specific map_cpu_to_node() chunk is no longer necessary. Dropped.
--- arch/x86/include/asm/numa.h | 5 ++++ arch/x86/include/asm/numa_32.h | 1 - arch/x86/include/asm/numa_64.h | 4 --- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/smpboot.c | 47 ----------------------------------- arch/x86/mm/numa.c | 53 ++++++++++++++++++++++++++++++++++++++- arch/x86/mm/numa_64.c | 40 +++++++++++------------------- 7 files changed, 72 insertions(+), 80 deletions(-)
arch/x86/include/asm/numa.h +5 -0
@@ -1,6 +1,7 @@#ifndef _ASM_X86_NUMA_H#define _ASM_X86_NUMA_H +#include <asm/topology.h> #include <asm/apicdef.h> #ifdef CONFIG_NUMA
@@ -33,9 +34,13 @@ static inline void set_apicid_to_node(int apicid, s16 node)#ifdef CONFIG_NUMA extern void __cpuinit numa_set_node (int cpu,int node);extern void __cpuinit numa_clear_node (int cpu); +extern void __cpuinit numa_add_cpu (int cpu); +extern void __cpuinit numa_remove_cpu (int cpu);#else /* CONFIG_NUMA */ static inline void numa_set_node (int cpu,int node) { }static inline void numa_clear_node (int cpu) { } +static inline void numa_add_cpu (int cpu) { } +static inline void numa_remove_cpu (int cpu) { }#endif /* CONFIG_NUMA */ #endif /* _ASM_X86_NUMA_H */
arch/x86/include/asm/numa_32.h +0 -1
@@ -2,7 +2,6 @@#define _ASM_X86_NUMA_32_Hextern int pxm_to_nid (int pxm); -extern void numa_remove_cpu (int cpu);#ifdef CONFIG_NUMA extern int __cpuinit numa_cpu_node (int apicid);
arch/x86/include/asm/numa_64.h +0 -4
@@ -30,8 +30,6 @@ extern void setup_node_bootmem(int nodeid, unsigned long start,extern void __init init_cpu_to_node (void );extern int __cpuinit numa_cpu_node (int cpu); -extern void __cpuinit numa_add_cpu (int cpu); -extern void __cpuinit numa_remove_cpu (int cpu);#ifdef CONFIG_NUMA_EMU #define FAKE_NODE_MIN_SIZE ((u64)32 << 20)
@@ -40,8 +38,6 @@ extern void __cpuinit numa_remove_cpu(int cpu);#else static inline void init_cpu_to_node (void ) { }static inline int numa_cpu_node (int cpu) {return NUMA_NO_NODE ; } -static inline void numa_add_cpu (int cpu,int node) { } -static inline void numa_remove_cpu (int cpu) { }#endif #endif /* _ASM_X86_NUMA_64_H */
arch/x86/kernel/cpu/common.c +1 -1
@@ -869,7 +869,7 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)select_idle_routine (c); -#if defined(CONFIG_NUMA ) && defined(CONFIG_X86_64 ) +#ifdef CONFIG_NUMA numa_add_cpu (smp_processor_id ());#endif }
arch/x86/kernel/smpboot.c +0 -47
71 lines not on this page · raw message
arch/x86/mm/numa.c +51 -2
68 lines not on this page · raw message
arch/x86/mm/numa_64.c +15 -25
@@ -740,19 +740,18 @@ int __cpuinit numa_cpu_node(int cpu)return NUMA_NO_NODE ; } -#ifndef CONFIG_DEBUG_PER_CPU_MAPS - -#ifndef CONFIG_NUMA_EMU -void __cpuinit numa_add_cpu(int cpu) -{ - cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]); -} - -void __cpuinit numa_remove_cpu(int cpu) -{ - cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]); -} -#else +/* +* UGLINESS AHEAD: Currently, CONFIG_NUMA_EMU is 64bit only and makes use +* of 64bit specific data structures. The distinction is artificial and +* should be removed. numa_{add|remove}_cpu() are implemented in numa.c +* for both 32 and 64bit when CONFIG_NUMA_EMU is disabled but here when +* enabled. +* +* NUMA emulation is planned to be made generic and the following and other +* related code should be moved to numa.c. +*/ +#ifdef CONFIG_NUMA_EMU +# ifndef CONFIG_DEBUG_PER_CPU_MAPS void __cpuinit numa_add_cpu(int cpu) { unsigned long addr;
@@ -792,13 +791,7 @@ void __cpuinit numa_remove_cpu(int cpu)for_each_online_node (i) cpumask_clear_cpu(cpu, node_to_cpumask_map[i]); } -#endif /* !CONFIG_NUMA_EMU */ - -#else /* CONFIG_DEBUG_PER_CPU_MAPS */ - -/* -* --------- debug versions of the numa functions --------- -*/ +# else /* !CONFIG_DEBUG_PER_CPU_MAPS */ static void __cpuinit numa_set_cpumask (int cpu,int enable) {int node =early_cpu_to_node (cpu);
@@ -841,8 +834,5 @@ void __cpuinit numa_remove_cpu(int cpu) {numa_set_cpumask (cpu,0 ); } -/* -* --------- end of debug versions of the numa functions --------- -*/ - -#endif /* CONFIG_DEBUG_PER_CPU_MAPS */ +# endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ +#endif /* CONFIG_NUMA_EMU */
Signature · 1 line
1.7.1
PATCH 16/16 x86: Unify NUMA initialization between 32 and 64bit
In reply to Tejun HeoNow that everything else is unified, NUMA initialization can be unified too.
* numa_init_array() and init_cpu_to_node() are moved from numa_64 to numa.
* numa_32::initmem_init() is updated to call numa_init_array() and setup_arch() to call init_cpu_to_node() on 32bit too.
* x86_cpu_to_node_map is now initialized to NUMA_NO_NODE on 32bit too. This is safe now as numa_init_array() will initialize it early during boot.
This makes NUMA mapping fully initialized before setup_per_cpu_areas() on 32bit too and thus makes the first percpu chunk which contains all the static variables and some of dynamic area allocated with NUMA affinity correctly considered.
--- arch/x86/include/asm/numa.h | 4 ++ arch/x86/include/asm/numa_64.h | 3 -- arch/x86/kernel/setup.c | 2 - arch/x86/mm/numa.c | 76 +++++++++++++++++++++++++++++++++++++-- arch/x86/mm/numa_32.c | 1 + arch/x86/mm/numa_64.c | 75 --------------------------------------- 6 files changed, 77 insertions(+), 84 deletions(-)
arch/x86/include/asm/numa.h +4 -0
@@ -34,11 +34,15 @@ static inline void set_apicid_to_node(int apicid, s16 node)#ifdef CONFIG_NUMA extern void __cpuinit numa_set_node (int cpu,int node);extern void __cpuinit numa_clear_node (int cpu); +extern void __init numa_init_array (void ); +extern void __init init_cpu_to_node (void );extern void __cpuinit numa_add_cpu (int cpu);extern void __cpuinit numa_remove_cpu (int cpu);#else /* CONFIG_NUMA */ static inline void numa_set_node (int cpu,int node) { }static inline void numa_clear_node (int cpu) { } +static inline void numa_init_array (void ) { } +static inline void init_cpu_to_node (void ) { }static inline void numa_add_cpu (int cpu) { }static inline void numa_remove_cpu (int cpu) { }#endif /* CONFIG_NUMA */
arch/x86/include/asm/numa_64.h +0 -3
@@ -13,7 +13,6 @@ extern int compute_hash_shift(struct bootnode *nodes, int numblks,#define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT)) -extern void numa_init_array (void );extern int numa_off;extern unsigned long numa_free_all_bootmem (void );
@@ -28,7 +27,6 @@ extern void setup_node_bootmem(int nodeid, unsigned long start,*/ #define NODE_MIN_SIZE (4*1024*1024) -extern void __init init_cpu_to_node (void );extern int __cpuinit numa_cpu_node (int cpu);#ifdef CONFIG_NUMA_EMU
@@ -36,7 +34,6 @@ extern int __cpuinit numa_cpu_node(int cpu);#define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL))#endif /* CONFIG_NUMA_EMU */ #else -static inline void init_cpu_to_node (void ) { }static inline int numa_cpu_node (int cpu) {return NUMA_NO_NODE ; }#endif
arch/x86/kernel/setup.c +0 -2
@@ -1030,9 +1030,7 @@ void __init setup_arch(char **cmdline_p)prefill_possible_map (); -#ifdef CONFIG_X86_64 init_cpu_to_node (); -#endif init_apic_mappings ();ioapic_and_gsi_init ();
arch/x86/mm/numa.c +72 -4
89 lines not on this page · raw message
arch/x86/mm/numa_32.c +1 -0
@@ -367,6 +367,7 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,*/ get_memcfg_numa (); +numa_init_array (); kva_pages =roundup (calculate_numa_remap_pages (),PTRS_PER_PTE );
arch/x86/mm/numa_64.c +0 -75
87 lines not on this page · raw message
Signature · 1 line
1.7.1
H. Peter Anvin
reviewerQuoted 21 lines · Tejun Heo
The only change from the last take[L] is that it's now based on tip/x86/numa. Unfortunately, some of the collisions weren't trivial and led to some ugliness.
Commit
c1c3443c("x86, numa: Fake node-to-cpumask for NUMA emulation") introduced hard dependency onx86_64into numa_add/remove_cpu() whenCONFIG_NUMA_EMUis enabled. 0015 has been updated so that the 32/64 bit common versions used when !CONFIG_NUMA_EMU are innuma.cwhileCONFIG_NUMA_EMUvariants are innuma_64.c.This is ugly but still better than before. IIUC, Shaohui's patchsets is going to unify NUMA emulation across 32 and 64bit, which should remove the above ugliness. I haven't looked through the patchset yet but after skimming through the current
NUMA_EMUcode, here are some of my thoughts, FWIW.* There's no reason for different NUMA config methods to construct different data structures. They all, including 32bit, can build a single set of data structures.
Quoted 9 lines
* Then, unification of
NUMA_EMUwould naturally follow. There's no reason to think about whether the underlying NUMA and proximity information is provided by ACPI, AMD or whatever. It just needs to manipulate the processed data.Let's _please_ head that way instead of adding more gluing codes and hacks everywhere. It would be a bit more churn but I don't think there's any other sustainable way.
Agreed 100%.
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Hello,
Quoted 2 lines · Tejun Heo
This is the fourth take of unify-x86_32-and-64-NUMA-init-paths patchset.
hpa, shall I refresh and resend?
Thanks.
Signature · 1 line
tejun
H. Peter Anvin
reviewerYes, please.
Quoted 12 lines · Tejun Heo
Hello,
Quoted 2 lines · Tejun Heo
This is the fourth take of unify-x86_32-and-64-NUMA-init-paths patchset.
hpa, shall I refresh and resend?
Thanks.
Signature · 1 line
tejun
Signature · 1 line
Sent from my mobile phone. Please pardon any lack of formatting.