diff options
author | Zwane Mwaikambo <zwane@arm.linux.org.uk> | 2005-09-03 18:56:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:06:13 -0400 |
commit | 4ad8d38342430f8b52f7a8458dce90caf8c8ca64 (patch) | |
tree | 090c471fdb44d8fe88c52e95be0e8e43e31fcd5a /arch/i386 | |
parent | d7271b14b2e9e5905aba0fbf5c4dc4f8980c0cb2 (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>
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/mpparse.c | 8 | ||||
-rw-r--r-- | arch/i386/kernel/smpboot.c | 3 | ||||
-rw-r--r-- | arch/i386/mach-voyager/voyager_smp.c | 3 |
3 files changed, 13 insertions, 1 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 | ||
123 | static void __init MP_processor_info (struct mpc_config_processor *m) | 123 | static 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); | |||
88 | cpumask_t cpu_callin_map; | 88 | cpumask_t cpu_callin_map; |
89 | cpumask_t cpu_callout_map; | 89 | cpumask_t cpu_callout_map; |
90 | EXPORT_SYMBOL(cpu_callout_map); | 90 | EXPORT_SYMBOL(cpu_callout_map); |
91 | cpumask_t cpu_possible_map; | ||
92 | EXPORT_SYMBOL(cpu_possible_map); | ||
91 | static cpumask_t smp_commenced_mask; | 93 | static 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; | |||
242 | cpumask_t cpu_callin_map = CPU_MASK_NONE; | 242 | cpumask_t cpu_callin_map = CPU_MASK_NONE; |
243 | cpumask_t cpu_callout_map = CPU_MASK_NONE; | 243 | cpumask_t cpu_callout_map = CPU_MASK_NONE; |
244 | EXPORT_SYMBOL(cpu_callout_map); | 244 | EXPORT_SYMBOL(cpu_callout_map); |
245 | cpumask_t cpu_possible_map = CPU_MASK_ALL; | ||
246 | EXPORT_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) */ |
247 | static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; | 249 | static __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 | ||
1915 | int __devinit | 1918 | int __devinit |