diff options
author | Mike Travis <travis@sgi.com> | 2007-10-19 14:35:03 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2007-10-19 14:35:03 -0400 |
commit | 71fff5e6ca1b738ac4742580e4c0ff79d906f6c8 (patch) | |
tree | 390e67123d684ab7f490291db987e097e5b3c728 | |
parent | dbeb2be21d678c49a8d8bbf774903df15dd55474 (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.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/genapic_64.c | 15 | ||||
-rw-r--r-- | arch/x86/kernel/genapic_flat_64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/mpparse_64.c | 15 | ||||
-rw-r--r-- | arch/x86/kernel/setup_64.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/smp_32.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot_32.c | 22 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot_64.c | 23 | ||||
-rw-r--r-- | arch/x86/mm/numa_64.c | 2 | ||||
-rw-r--r-- | include/asm-x86/ipi.h | 2 | ||||
-rw-r--r-- | include/asm-x86/smp_32.h | 6 | ||||
-rw-r--r-- | include/asm-x86/smp_64.h | 6 |
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 | ||
556 | int acpi_unmap_lsapic(int cpu) | 556 | int 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 | /* |
28 | u8 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 | */ | ||
35 | u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata | ||
29 | = { [0 ... NR_CPUS-1] = BAD_APICID }; | 36 | = { [0 ... NR_CPUS-1] = BAD_APICID }; |
30 | EXPORT_SYMBOL(x86_cpu_to_apicid); | 37 | void *x86_cpu_to_apicid_ptr; |
38 | DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID; | ||
39 | EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid); | ||
31 | 40 | ||
32 | struct genapic __read_mostly *genapic = &apic_flat; | 41 | struct 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 | ||
89 | static void __cpuinit MP_processor_info (struct mpc_config_processor *m) | 89 | static 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; | |||
92 | struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; | 92 | struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; |
93 | EXPORT_SYMBOL(cpu_data); | 93 | EXPORT_SYMBOL(cpu_data); |
94 | 94 | ||
95 | u8 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 |
97 | EXPORT_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 | */ | ||
101 | u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata = | ||
102 | { [0 ... NR_CPUS-1] = BAD_APICID }; | ||
103 | void *x86_cpu_to_apicid_ptr; | ||
104 | DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID; | ||
105 | EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid); | ||
98 | 106 | ||
99 | u8 apicid_2_node[MAX_APICID]; | 107 | u8 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 | */ | ||
849 | void __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); | |||
39 | extern void unlock_ipi_call_lock(void); | 39 | extern void unlock_ipi_call_lock(void); |
40 | 40 | ||
41 | #define MAX_APICID 256 | 41 | #define MAX_APICID 256 |
42 | extern u8 x86_cpu_to_apicid[]; | 42 | extern u8 __initdata x86_cpu_to_apicid_init[]; |
43 | extern void *x86_cpu_to_apicid_ptr; | ||
44 | DECLARE_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 | ||
46 | extern void set_cpu_sibling_map(int cpu); | 48 | extern 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 | */ |
89 | extern u8 x86_cpu_to_apicid[NR_CPUS]; /* physical ID */ | 89 | extern u8 __initdata x86_cpu_to_apicid_init[]; |
90 | extern void *x86_cpu_to_apicid_ptr; | ||
91 | DECLARE_PER_CPU(u8, x86_cpu_to_apicid); /* physical ID */ | ||
90 | extern u8 bios_cpu_apicid[]; | 92 | extern u8 bios_cpu_apicid[]; |
91 | 93 | ||
92 | static inline int cpu_present_to_apicid(int mps_cpu) | 94 | static 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 */ |