Commit 71fff5e6ca1b738ac4742580e4c0ff79d906f6c8

Authored by Mike Travis
Committed by Thomas Gleixner
1 parent dbeb2be21d

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>

Showing 12 changed files with 80 additions and 22 deletions Side-by-side Diff

arch/x86/kernel/acpi/boot.c
... ... @@ -555,7 +555,7 @@
555 555  
556 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 559 cpu_clear(cpu, cpu_present_map);
560 560 num_processors--;
561 561  
arch/x86/kernel/genapic_64.c
... ... @@ -24,10 +24,19 @@
24 24 #include <acpi/acpi_bus.h>
25 25 #endif
26 26  
27   -/* which logical CPU number maps to which CPU (physical APIC ID) */
28   -u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly
  27 +/*
  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 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 41 struct genapic __read_mostly *genapic = &apic_flat;
33 42  
arch/x86/kernel/genapic_flat_64.c
... ... @@ -172,7 +172,7 @@
172 172 */
173 173 cpu = first_cpu(cpumask);
174 174 if ((unsigned)cpu < NR_CPUS)
175   - return x86_cpu_to_apicid[cpu];
  175 + return per_cpu(x86_cpu_to_apicid, cpu);
176 176 else
177 177 return BAD_APICID;
178 178 }
arch/x86/kernel/mpparse_64.c
... ... @@ -86,7 +86,7 @@
86 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 91 int cpu;
92 92 cpumask_t tmp_map;
... ... @@ -123,7 +123,18 @@
123 123 cpu = 0;
124 124 }
125 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 139 cpu_set(cpu, cpu_possible_map);
129 140 cpu_set(cpu, cpu_present_map);
arch/x86/kernel/setup_64.c
... ... @@ -271,6 +271,11 @@
271 271  
272 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 279 #ifdef CONFIG_ACPI
275 280 /*
276 281 * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
arch/x86/kernel/smp_32.c
... ... @@ -676,7 +676,7 @@
676 676 int i;
677 677  
678 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 680 return i;
681 681 }
682 682 return -1;
arch/x86/kernel/smpboot_32.c
... ... @@ -92,9 +92,17 @@
92 92 struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
93 93 EXPORT_SYMBOL(cpu_data);
94 94  
95   -u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
96   - { [0 ... NR_CPUS-1] = 0xff };
97   -EXPORT_SYMBOL(x86_cpu_to_apicid);
  95 +/*
  96 + * The following static array is used during kernel startup
  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 107 u8 apicid_2_node[MAX_APICID];
100 108  
... ... @@ -804,7 +812,7 @@
804 812  
805 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 817 * This grunge runs the startup process for
810 818 * the targeted processor.
... ... @@ -866,7 +874,7 @@
866 874 cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
867 875 cpucount--;
868 876 } else {
869   - x86_cpu_to_apicid[cpu] = apicid;
  877 + per_cpu(x86_cpu_to_apicid, cpu) = apicid;
870 878 cpu_set(cpu, cpu_present_map);
871 879 }
872 880  
... ... @@ -915,7 +923,7 @@
915 923 struct warm_boot_cpu_info info;
916 924 int apicid, ret;
917 925  
918   - apicid = x86_cpu_to_apicid[cpu];
  926 + apicid = per_cpu(x86_cpu_to_apicid, cpu);
919 927 if (apicid == BAD_APICID) {
920 928 ret = -ENODEV;
921 929 goto exit;
... ... @@ -965,7 +973,7 @@
965 973  
966 974 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
967 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 978 current_thread_info()->cpu = 0;
971 979  
arch/x86/kernel/smpboot_64.c
... ... @@ -694,7 +694,7 @@
694 694 clear_node_cpumask(cpu); /* was set by numa_add_cpu */
695 695 cpu_clear(cpu, cpu_present_map);
696 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 698 return -EIO;
699 699 }
700 700  
... ... @@ -841,6 +841,26 @@
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 864 * Prepare for SMP bootup. The MP table or ACPI has been read
845 865 * earlier. Just do some sanity checking here and enable APIC mode.
846 866 */
... ... @@ -849,6 +869,7 @@
849 869 nmi_watchdog_default();
850 870 current_cpu_data = boot_cpu_data;
851 871 current_thread_info()->cpu = 0; /* needed? */
  872 + smp_set_apicids();
852 873 set_cpu_sibling_map(0);
853 874  
854 875 if (smp_sanity_check(max_cpus) < 0) {
arch/x86/mm/numa_64.c
... ... @@ -612,7 +612,7 @@
612 612 {
613 613 int i;
614 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 616 if (apicid == BAD_APICID)
617 617 continue;
618 618 if (apicid_to_node[apicid] == NUMA_NO_NODE)
include/asm-x86/ipi.h
... ... @@ -119,7 +119,7 @@
119 119 */
120 120 local_irq_save(flags);
121 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 123 vector, APIC_DEST_PHYSICAL);
124 124 }
125 125 local_irq_restore(flags);
include/asm-x86/smp_32.h
... ... @@ -39,9 +39,11 @@
39 39 extern void unlock_ipi_call_lock(void);
40 40  
41 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 48 extern void set_cpu_sibling_map(int cpu);
47 49  
include/asm-x86/smp_64.h
... ... @@ -86,7 +86,9 @@
86 86 * Some lowlevel functions might want to know about
87 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 92 extern u8 bios_cpu_apicid[];
91 93  
92 94 static inline int cpu_present_to_apicid(int mps_cpu)
... ... @@ -117,7 +119,7 @@
117 119 }
118 120  
119 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 123 #else
122 124 #define cpu_physical_id(cpu) boot_cpu_id
123 125 #endif /* !CONFIG_SMP */