aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZwane Mwaikambo <zwane@arm.linux.org.uk>2005-09-03 18:56:51 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:06:13 -0400
commit4ad8d38342430f8b52f7a8458dce90caf8c8ca64 (patch)
tree090c471fdb44d8fe88c52e95be0e8e43e31fcd5a
parentd7271b14b2e9e5905aba0fbf5c4dc4f8980c0cb2 (diff)
[PATCH] i386 boottime for_each_cpu broken
for_each_cpu walks through all processors in cpu_possible_map, which is defined as cpu_callout_map on i386 and isn't initialised until all processors have been booted. This breaks things which do for_each_cpu iterations early during boot. So, define cpu_possible_map as a bitmap with NR_CPUS bits populated. This was triggered by a patch i'm working on which does alloc_percpu before bringing up secondary processors. From: Alexander Nyberg <alexn@telia.com> i386-boottime-for_each_cpu-broken.patch i386-boottime-for_each_cpu-broken-fix.patch The SMP version of __alloc_percpu checks the cpu_possible_map before allocating memory for a certain cpu. With the above patches the BSP cpuid is never set in cpu_possible_map which breaks CONFIG_SMP on uniprocessor machines (as soon as someone tries to dereference something allocated via __alloc_percpu, which in fact is never allocated since the cpu is not set in cpu_possible_map). Signed-off-by: Zwane Mwaikambo <zwane@arm.linux.org.uk> Signed-off-by: Alexander Nyberg <alexn@telia.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/kernel/mpparse.c8
-rw-r--r--arch/i386/kernel/smpboot.c3
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c3
-rw-r--r--include/asm-i386/smp.h2
4 files changed, 14 insertions, 2 deletions
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 788efffa9930..5d0b9a8fc43d 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -122,7 +122,7 @@ static int MP_valid_apicid(int apicid, int version)
122 122
123static void __init MP_processor_info (struct mpc_config_processor *m) 123static void __init MP_processor_info (struct mpc_config_processor *m)
124{ 124{
125 int ver, apicid; 125 int ver, apicid, cpu, found_bsp = 0;
126 physid_mask_t tmp; 126 physid_mask_t tmp;
127 127
128 if (!(m->mpc_cpuflag & CPU_ENABLED)) 128 if (!(m->mpc_cpuflag & CPU_ENABLED))
@@ -181,6 +181,7 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
181 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { 181 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
182 Dprintk(" Bootup CPU\n"); 182 Dprintk(" Bootup CPU\n");
183 boot_cpu_physical_apicid = m->mpc_apicid; 183 boot_cpu_physical_apicid = m->mpc_apicid;
184 found_bsp = 1;
184 } 185 }
185 186
186 if (num_processors >= NR_CPUS) { 187 if (num_processors >= NR_CPUS) {
@@ -204,6 +205,11 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
204 return; 205 return;
205 } 206 }
206 207
208 if (found_bsp)
209 cpu = 0;
210 else
211 cpu = num_processors - 1;
212 cpu_set(cpu, cpu_possible_map);
207 tmp = apicid_to_cpu_present(apicid); 213 tmp = apicid_to_cpu_present(apicid);
208 physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp); 214 physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp);
209 215
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 8e950cdff1a0..5e4893d2b9f2 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -88,6 +88,8 @@ EXPORT_SYMBOL(cpu_online_map);
88cpumask_t cpu_callin_map; 88cpumask_t cpu_callin_map;
89cpumask_t cpu_callout_map; 89cpumask_t cpu_callout_map;
90EXPORT_SYMBOL(cpu_callout_map); 90EXPORT_SYMBOL(cpu_callout_map);
91cpumask_t cpu_possible_map;
92EXPORT_SYMBOL(cpu_possible_map);
91static cpumask_t smp_commenced_mask; 93static cpumask_t smp_commenced_mask;
92 94
93/* TSC's upper 32 bits can't be written in eariler CPU (before prescott), there 95/* TSC's upper 32 bits can't be written in eariler CPU (before prescott), there
@@ -1265,6 +1267,7 @@ void __devinit smp_prepare_boot_cpu(void)
1265 cpu_set(smp_processor_id(), cpu_online_map); 1267 cpu_set(smp_processor_id(), cpu_online_map);
1266 cpu_set(smp_processor_id(), cpu_callout_map); 1268 cpu_set(smp_processor_id(), cpu_callout_map);
1267 cpu_set(smp_processor_id(), cpu_present_map); 1269 cpu_set(smp_processor_id(), cpu_present_map);
1270 cpu_set(smp_processor_id(), cpu_possible_map);
1268 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; 1271 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
1269} 1272}
1270 1273
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index 16790b798613..46b0cf4a31e0 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -242,6 +242,8 @@ static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
242cpumask_t cpu_callin_map = CPU_MASK_NONE; 242cpumask_t cpu_callin_map = CPU_MASK_NONE;
243cpumask_t cpu_callout_map = CPU_MASK_NONE; 243cpumask_t cpu_callout_map = CPU_MASK_NONE;
244EXPORT_SYMBOL(cpu_callout_map); 244EXPORT_SYMBOL(cpu_callout_map);
245cpumask_t cpu_possible_map = CPU_MASK_ALL;
246EXPORT_SYMBOL(cpu_possible_map);
245 247
246/* The per processor IRQ masks (these are usually kept in sync) */ 248/* The per processor IRQ masks (these are usually kept in sync) */
247static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; 249static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
@@ -1910,6 +1912,7 @@ void __devinit smp_prepare_boot_cpu(void)
1910{ 1912{
1911 cpu_set(smp_processor_id(), cpu_online_map); 1913 cpu_set(smp_processor_id(), cpu_online_map);
1912 cpu_set(smp_processor_id(), cpu_callout_map); 1914 cpu_set(smp_processor_id(), cpu_callout_map);
1915 cpu_set(smp_processor_id(), cpu_possible_map);
1913} 1916}
1914 1917
1915int __devinit 1918int __devinit
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
index a283738b80b3..13250199976d 100644
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -59,7 +59,7 @@ extern void cpu_uninit(void);
59 59
60extern cpumask_t cpu_callout_map; 60extern cpumask_t cpu_callout_map;
61extern cpumask_t cpu_callin_map; 61extern cpumask_t cpu_callin_map;
62#define cpu_possible_map cpu_callout_map 62extern cpumask_t cpu_possible_map;
63 63
64/* We don't mark CPUs online until __cpu_up(), so we need another measure */ 64/* We don't mark CPUs online until __cpu_up(), so we need another measure */
65static inline int num_booting_cpus(void) 65static inline int num_booting_cpus(void)