aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2007-10-19 14:35:03 -0400
committerThomas Gleixner <tglx@linutronix.de>2007-10-19 14:35:03 -0400
commit71fff5e6ca1b738ac4742580e4c0ff79d906f6c8 (patch)
tree390e67123d684ab7f490291db987e097e5b3c728
parentdbeb2be21d678c49a8d8bbf774903df15dd55474 (diff)
x86: convert cpu_to_apicid to be a per cpu variable
This patch converts the x86_cpu_to_apicid array to be a per cpu variable. This saves sizeof(apicid) * NR unused cpus. Access is mostly from startup and CPU HOTPLUG functions. MP_processor_info() is one of the functions that require access to the x86_cpu_to_apicid array before the per_cpu data area is setup. For this case, a pointer to the __initdata array is initialized in setup_arch() and removed in smp_prepare_cpus() after the per_cpu data area is initialized. A second change is included to change the initial array value of ARCH i386 from 0xff to BAD_APICID to be consistent with ARCH x86_64. Signed-off-by: Mike Travis <travis@sgi.com> Cc: Andi Kleen <ak@suse.de> Cc: Christoph Lameter <clameter@sgi.com> Cc: "Siddha, Suresh B" <suresh.b.siddha@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/kernel/acpi/boot.c2
-rw-r--r--arch/x86/kernel/genapic_64.c15
-rw-r--r--arch/x86/kernel/genapic_flat_64.c2
-rw-r--r--arch/x86/kernel/mpparse_64.c15
-rw-r--r--arch/x86/kernel/setup_64.c5
-rw-r--r--arch/x86/kernel/smp_32.c2
-rw-r--r--arch/x86/kernel/smpboot_32.c22
-rw-r--r--arch/x86/kernel/smpboot_64.c23
-rw-r--r--arch/x86/mm/numa_64.c2
-rw-r--r--include/asm-x86/ipi.h2
-rw-r--r--include/asm-x86/smp_32.h6
-rw-r--r--include/asm-x86/smp_64.h6
12 files changed, 80 insertions, 22 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index afd2afe9102d..f28b2e251b1d 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -555,7 +555,7 @@ EXPORT_SYMBOL(acpi_map_lsapic);
555 555
556int acpi_unmap_lsapic(int cpu) 556int acpi_unmap_lsapic(int cpu)
557{ 557{
558 x86_cpu_to_apicid[cpu] = -1; 558 per_cpu(x86_cpu_to_apicid, cpu) = -1;
559 cpu_clear(cpu, cpu_present_map); 559 cpu_clear(cpu, cpu_present_map);
560 num_processors--; 560 num_processors--;
561 561
diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c
index 4ae03e3e8294..ce703e21c912 100644
--- a/arch/x86/kernel/genapic_64.c
+++ b/arch/x86/kernel/genapic_64.c
@@ -24,10 +24,19 @@
24#include <acpi/acpi_bus.h> 24#include <acpi/acpi_bus.h>
25#endif 25#endif
26 26
27/* which logical CPU number maps to which CPU (physical APIC ID) */ 27/*
28u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly 28 * which logical CPU number maps to which CPU (physical APIC ID)
29 *
30 * The following static array is used during kernel startup
31 * and the x86_cpu_to_apicid_ptr contains the address of the
32 * array during this time. Is it zeroed when the per_cpu
33 * data area is removed.
34 */
35u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata
29 = { [0 ... NR_CPUS-1] = BAD_APICID }; 36 = { [0 ... NR_CPUS-1] = BAD_APICID };
30EXPORT_SYMBOL(x86_cpu_to_apicid); 37void *x86_cpu_to_apicid_ptr;
38DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
39EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
31 40
32struct genapic __read_mostly *genapic = &apic_flat; 41struct genapic __read_mostly *genapic = &apic_flat;
33 42
diff --git a/arch/x86/kernel/genapic_flat_64.c b/arch/x86/kernel/genapic_flat_64.c
index 91c7526768ee..07352b74bda6 100644
--- a/arch/x86/kernel/genapic_flat_64.c
+++ b/arch/x86/kernel/genapic_flat_64.c
@@ -172,7 +172,7 @@ static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask)
172 */ 172 */
173 cpu = first_cpu(cpumask); 173 cpu = first_cpu(cpumask);
174 if ((unsigned)cpu < NR_CPUS) 174 if ((unsigned)cpu < NR_CPUS)
175 return x86_cpu_to_apicid[cpu]; 175 return per_cpu(x86_cpu_to_apicid, cpu);
176 else 176 else
177 return BAD_APICID; 177 return BAD_APICID;
178} 178}
diff --git a/arch/x86/kernel/mpparse_64.c b/arch/x86/kernel/mpparse_64.c
index 8bf0ca03ac8e..4336c0fc3b81 100644
--- a/arch/x86/kernel/mpparse_64.c
+++ b/arch/x86/kernel/mpparse_64.c
@@ -86,7 +86,7 @@ static int __init mpf_checksum(unsigned char *mp, int len)
86 return sum & 0xFF; 86 return sum & 0xFF;
87} 87}
88 88
89static void __cpuinit MP_processor_info (struct mpc_config_processor *m) 89static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
90{ 90{
91 int cpu; 91 int cpu;
92 cpumask_t tmp_map; 92 cpumask_t tmp_map;
@@ -123,7 +123,18 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
123 cpu = 0; 123 cpu = 0;
124 } 124 }
125 bios_cpu_apicid[cpu] = m->mpc_apicid; 125 bios_cpu_apicid[cpu] = m->mpc_apicid;
126 x86_cpu_to_apicid[cpu] = m->mpc_apicid; 126 /*
127 * We get called early in the the start_kernel initialization
128 * process when the per_cpu data area is not yet setup, so we
129 * use a static array that is removed after the per_cpu data
130 * area is created.
131 */
132 if (x86_cpu_to_apicid_ptr) {
133 u8 *x86_cpu_to_apicid = (u8 *)x86_cpu_to_apicid_ptr;
134 x86_cpu_to_apicid[cpu] = m->mpc_apicid;
135 } else {
136 per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid;
137 }
127 138
128 cpu_set(cpu, cpu_possible_map); 139 cpu_set(cpu, cpu_possible_map);
129 cpu_set(cpu, cpu_present_map); 140 cpu_set(cpu, cpu_present_map);
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index 5a19f0cc5b67..94630c66470e 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -271,6 +271,11 @@ void __init setup_arch(char **cmdline_p)
271 271
272 dmi_scan_machine(); 272 dmi_scan_machine();
273 273
274#ifdef CONFIG_SMP
275 /* setup to use the static apicid table during kernel startup */
276 x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init;
277#endif
278
274#ifdef CONFIG_ACPI 279#ifdef CONFIG_ACPI
275 /* 280 /*
276 * Initialize the ACPI boot-time table parser (gets the RSDP and SDT). 281 * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
diff --git a/arch/x86/kernel/smp_32.c b/arch/x86/kernel/smp_32.c
index 791d9f8036ae..4974c3d2a0a6 100644
--- a/arch/x86/kernel/smp_32.c
+++ b/arch/x86/kernel/smp_32.c
@@ -676,7 +676,7 @@ static int convert_apicid_to_cpu(int apic_id)
676 int i; 676 int i;
677 677
678 for (i = 0; i < NR_CPUS; i++) { 678 for (i = 0; i < NR_CPUS; i++) {
679 if (x86_cpu_to_apicid[i] == apic_id) 679 if (per_cpu(x86_cpu_to_apicid, i) == apic_id)
680 return i; 680 return i;
681 } 681 }
682 return -1; 682 return -1;
diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c
index 65e5de7d64db..631be36ec2a9 100644
--- a/arch/x86/kernel/smpboot_32.c
+++ b/arch/x86/kernel/smpboot_32.c
@@ -92,9 +92,17 @@ static cpumask_t smp_commenced_mask;
92struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; 92struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
93EXPORT_SYMBOL(cpu_data); 93EXPORT_SYMBOL(cpu_data);
94 94
95u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = 95/*
96 { [0 ... NR_CPUS-1] = 0xff }; 96 * The following static array is used during kernel startup
97EXPORT_SYMBOL(x86_cpu_to_apicid); 97 * and the x86_cpu_to_apicid_ptr contains the address of the
98 * array during this time. Is it zeroed when the per_cpu
99 * data area is removed.
100 */
101u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata =
102 { [0 ... NR_CPUS-1] = BAD_APICID };
103void *x86_cpu_to_apicid_ptr;
104DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
105EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
98 106
99u8 apicid_2_node[MAX_APICID]; 107u8 apicid_2_node[MAX_APICID];
100 108
@@ -804,7 +812,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
804 812
805 irq_ctx_init(cpu); 813 irq_ctx_init(cpu);
806 814
807 x86_cpu_to_apicid[cpu] = apicid; 815 per_cpu(x86_cpu_to_apicid, cpu) = apicid;
808 /* 816 /*
809 * This grunge runs the startup process for 817 * This grunge runs the startup process for
810 * the targeted processor. 818 * the targeted processor.
@@ -866,7 +874,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
866 cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ 874 cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
867 cpucount--; 875 cpucount--;
868 } else { 876 } else {
869 x86_cpu_to_apicid[cpu] = apicid; 877 per_cpu(x86_cpu_to_apicid, cpu) = apicid;
870 cpu_set(cpu, cpu_present_map); 878 cpu_set(cpu, cpu_present_map);
871 } 879 }
872 880
@@ -915,7 +923,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu)
915 struct warm_boot_cpu_info info; 923 struct warm_boot_cpu_info info;
916 int apicid, ret; 924 int apicid, ret;
917 925
918 apicid = x86_cpu_to_apicid[cpu]; 926 apicid = per_cpu(x86_cpu_to_apicid, cpu);
919 if (apicid == BAD_APICID) { 927 if (apicid == BAD_APICID) {
920 ret = -ENODEV; 928 ret = -ENODEV;
921 goto exit; 929 goto exit;
@@ -965,7 +973,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
965 973
966 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); 974 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
967 boot_cpu_logical_apicid = logical_smp_processor_id(); 975 boot_cpu_logical_apicid = logical_smp_processor_id();
968 x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; 976 per_cpu(x86_cpu_to_apicid, 0) = boot_cpu_physical_apicid;
969 977
970 current_thread_info()->cpu = 0; 978 current_thread_info()->cpu = 0;
971 979
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
index e351ac4ab5b1..c3e8668c5278 100644
--- a/arch/x86/kernel/smpboot_64.c
+++ b/arch/x86/kernel/smpboot_64.c
@@ -694,7 +694,7 @@ do_rest:
694 clear_node_cpumask(cpu); /* was set by numa_add_cpu */ 694 clear_node_cpumask(cpu); /* was set by numa_add_cpu */
695 cpu_clear(cpu, cpu_present_map); 695 cpu_clear(cpu, cpu_present_map);
696 cpu_clear(cpu, cpu_possible_map); 696 cpu_clear(cpu, cpu_possible_map);
697 x86_cpu_to_apicid[cpu] = BAD_APICID; 697 per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
698 return -EIO; 698 return -EIO;
699 } 699 }
700 700
@@ -841,6 +841,26 @@ static int __init smp_sanity_check(unsigned max_cpus)
841} 841}
842 842
843/* 843/*
844 * Copy apicid's found by MP_processor_info from initial array to the per cpu
845 * data area. The x86_cpu_to_apicid_init array is then expendable and the
846 * x86_cpu_to_apicid_ptr is zeroed indicating that the static array is no
847 * longer available.
848 */
849void __init smp_set_apicids(void)
850{
851 int cpu;
852
853 for_each_cpu_mask(cpu, cpu_possible_map) {
854 if (per_cpu_offset(cpu))
855 per_cpu(x86_cpu_to_apicid, cpu) =
856 x86_cpu_to_apicid_init[cpu];
857 }
858
859 /* indicate the static array will be going away soon */
860 x86_cpu_to_apicid_ptr = NULL;
861}
862
863/*
844 * Prepare for SMP bootup. The MP table or ACPI has been read 864 * Prepare for SMP bootup. The MP table or ACPI has been read
845 * earlier. Just do some sanity checking here and enable APIC mode. 865 * earlier. Just do some sanity checking here and enable APIC mode.
846 */ 866 */
@@ -849,6 +869,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
849 nmi_watchdog_default(); 869 nmi_watchdog_default();
850 current_cpu_data = boot_cpu_data; 870 current_cpu_data = boot_cpu_data;
851 current_thread_info()->cpu = 0; /* needed? */ 871 current_thread_info()->cpu = 0; /* needed? */
872 smp_set_apicids();
852 set_cpu_sibling_map(0); 873 set_cpu_sibling_map(0);
853 874
854 if (smp_sanity_check(max_cpus) < 0) { 875 if (smp_sanity_check(max_cpus) < 0) {
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 5eec5e56d07f..3d6926ba8995 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -612,7 +612,7 @@ void __init init_cpu_to_node(void)
612{ 612{
613 int i; 613 int i;
614 for (i = 0; i < NR_CPUS; i++) { 614 for (i = 0; i < NR_CPUS; i++) {
615 u8 apicid = x86_cpu_to_apicid[i]; 615 u8 apicid = x86_cpu_to_apicid_init[i];
616 if (apicid == BAD_APICID) 616 if (apicid == BAD_APICID)
617 continue; 617 continue;
618 if (apicid_to_node[apicid] == NUMA_NO_NODE) 618 if (apicid_to_node[apicid] == NUMA_NO_NODE)
diff --git a/include/asm-x86/ipi.h b/include/asm-x86/ipi.h
index a7c75ea408a8..6d011bd6067d 100644
--- a/include/asm-x86/ipi.h
+++ b/include/asm-x86/ipi.h
@@ -119,7 +119,7 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
119 */ 119 */
120 local_irq_save(flags); 120 local_irq_save(flags);
121 for_each_cpu_mask(query_cpu, mask) { 121 for_each_cpu_mask(query_cpu, mask) {
122 __send_IPI_dest_field(x86_cpu_to_apicid[query_cpu], 122 __send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, query_cpu),
123 vector, APIC_DEST_PHYSICAL); 123 vector, APIC_DEST_PHYSICAL);
124 } 124 }
125 local_irq_restore(flags); 125 local_irq_restore(flags);
diff --git a/include/asm-x86/smp_32.h b/include/asm-x86/smp_32.h
index ee46038d126c..9006f6041bf8 100644
--- a/include/asm-x86/smp_32.h
+++ b/include/asm-x86/smp_32.h
@@ -39,9 +39,11 @@ extern void lock_ipi_call_lock(void);
39extern void unlock_ipi_call_lock(void); 39extern void unlock_ipi_call_lock(void);
40 40
41#define MAX_APICID 256 41#define MAX_APICID 256
42extern u8 x86_cpu_to_apicid[]; 42extern u8 __initdata x86_cpu_to_apicid_init[];
43extern void *x86_cpu_to_apicid_ptr;
44DECLARE_PER_CPU(u8, x86_cpu_to_apicid);
43 45
44#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu] 46#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
45 47
46extern void set_cpu_sibling_map(int cpu); 48extern void set_cpu_sibling_map(int cpu);
47 49
diff --git a/include/asm-x86/smp_64.h b/include/asm-x86/smp_64.h
index 9d35018e54fe..f1545704e24e 100644
--- a/include/asm-x86/smp_64.h
+++ b/include/asm-x86/smp_64.h
@@ -86,7 +86,9 @@ static inline int hard_smp_processor_id(void)
86 * Some lowlevel functions might want to know about 86 * Some lowlevel functions might want to know about
87 * the real APIC ID <-> CPU # mapping. 87 * the real APIC ID <-> CPU # mapping.
88 */ 88 */
89extern u8 x86_cpu_to_apicid[NR_CPUS]; /* physical ID */ 89extern u8 __initdata x86_cpu_to_apicid_init[];
90extern void *x86_cpu_to_apicid_ptr;
91DECLARE_PER_CPU(u8, x86_cpu_to_apicid); /* physical ID */
90extern u8 bios_cpu_apicid[]; 92extern u8 bios_cpu_apicid[];
91 93
92static inline int cpu_present_to_apicid(int mps_cpu) 94static inline int cpu_present_to_apicid(int mps_cpu)
@@ -117,7 +119,7 @@ static __inline int logical_smp_processor_id(void)
117} 119}
118 120
119#ifdef CONFIG_SMP 121#ifdef CONFIG_SMP
120#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu] 122#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
121#else 123#else
122#define cpu_physical_id(cpu) boot_cpu_id 124#define cpu_physical_id(cpu) boot_cpu_id
123#endif /* !CONFIG_SMP */ 125#endif /* !CONFIG_SMP */