diff options
author | Brian Uhrain says <buhrain@rosettastone.com> | 2006-04-11 01:53:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-11 09:18:34 -0400 |
commit | 917b1f78a9871a1985004df09ed1eb2e0dc3bf4f (patch) | |
tree | fad71a349195be55c35d026c24422678c1b73e6e /arch/alpha | |
parent | 1c08ca89b07eeca241fcf1ec297d3ef173a999a9 (diff) |
[PATCH] alpha: SMP boot fixes
I've encountered two problems with 2.6.16 and newer kernels on my API CS20
(dual 833MHz Alpha 21264b processors). The first is the kernel OOPSing
because of a NULL pointer dereference while trying to populate SysFS with the
CPU information. The other is that only one processor was being brought up.
I've included a small Alpha-specific patch that fixes both problems.
The first problem was caused by the CPUs never being properly registered using
register_cpu(), the way it's done on other architectures.
The second problem has to do with the removal of hwrpb_cpu_present_mask in
arch/alpha/kernel/smp.c. In setup_smp() in the 2.6.15 kernel sources,
hwrpb_cpu_present_mask has a bit set for each processor that is probed, and
afterwards cpu_present_mask is set to the cpumask for the boot CPU. In the
same function of the same file in the 2.6.16 sources, instead of
hwrpb_cpu_present_mask being set, cpu_possible_map is updated for each probed
CPU. cpu_present_mask is still set to the cpumask of the boot CPU afterwards.
The problem lies in include/asm-alpha/smp.h, where cpu_possible_map is
#define'd to be cpu_present_mask.
Cleanups from: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
- cpu_present_mask and cpu_possible_map are essentially the same thing
on alpha, as it doesn't support CPU hotplug;
- allocate "struct cpu" only for present CPUs, like sparc64 does.
Static array of "struct cpu" is just a waste of memory.
Signed-off-by: Brian Uhrain <buhrain@rosettastone.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/alpha')
-rw-r--r-- | arch/alpha/kernel/setup.c | 17 | ||||
-rw-r--r-- | arch/alpha/kernel/smp.c | 8 |
2 files changed, 20 insertions, 5 deletions
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index a15e18a00258..558b83368559 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/config.h> /* CONFIG_ALPHA_LCA etc */ | 24 | #include <linux/config.h> /* CONFIG_ALPHA_LCA etc */ |
25 | #include <linux/mc146818rtc.h> | 25 | #include <linux/mc146818rtc.h> |
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/cpu.h> | ||
27 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
28 | #include <linux/init.h> | 29 | #include <linux/init.h> |
29 | #include <linux/string.h> | 30 | #include <linux/string.h> |
@@ -471,6 +472,22 @@ page_is_ram(unsigned long pfn) | |||
471 | return 0; | 472 | return 0; |
472 | } | 473 | } |
473 | 474 | ||
475 | static int __init | ||
476 | register_cpus(void) | ||
477 | { | ||
478 | int i; | ||
479 | |||
480 | for_each_possible_cpu(i) { | ||
481 | struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); | ||
482 | if (!p) | ||
483 | return -ENOMEM; | ||
484 | register_cpu(p, i, NULL); | ||
485 | } | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | arch_initcall(register_cpus); | ||
490 | |||
474 | void __init | 491 | void __init |
475 | setup_arch(char **cmdline_p) | 492 | setup_arch(char **cmdline_p) |
476 | { | 493 | { |
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 02c2db08114a..185255416e85 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c | |||
@@ -439,7 +439,7 @@ setup_smp(void) | |||
439 | if ((cpu->flags & 0x1cc) == 0x1cc) { | 439 | if ((cpu->flags & 0x1cc) == 0x1cc) { |
440 | smp_num_probed++; | 440 | smp_num_probed++; |
441 | /* Assume here that "whami" == index */ | 441 | /* Assume here that "whami" == index */ |
442 | cpu_set(i, cpu_possible_map); | 442 | cpu_set(i, cpu_present_mask); |
443 | cpu->pal_revision = boot_cpu_palrev; | 443 | cpu->pal_revision = boot_cpu_palrev; |
444 | } | 444 | } |
445 | 445 | ||
@@ -450,9 +450,8 @@ setup_smp(void) | |||
450 | } | 450 | } |
451 | } else { | 451 | } else { |
452 | smp_num_probed = 1; | 452 | smp_num_probed = 1; |
453 | cpu_set(boot_cpuid, cpu_possible_map); | 453 | cpu_set(boot_cpuid, cpu_present_mask); |
454 | } | 454 | } |
455 | cpu_present_mask = cpumask_of_cpu(boot_cpuid); | ||
456 | 455 | ||
457 | printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", | 456 | printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", |
458 | smp_num_probed, cpu_possible_map.bits[0]); | 457 | smp_num_probed, cpu_possible_map.bits[0]); |
@@ -488,9 +487,8 @@ void __devinit | |||
488 | smp_prepare_boot_cpu(void) | 487 | smp_prepare_boot_cpu(void) |
489 | { | 488 | { |
490 | /* | 489 | /* |
491 | * Mark the boot cpu (current cpu) as both present and online | 490 | * Mark the boot cpu (current cpu) as online |
492 | */ | 491 | */ |
493 | cpu_set(smp_processor_id(), cpu_present_mask); | ||
494 | cpu_set(smp_processor_id(), cpu_online_map); | 492 | cpu_set(smp_processor_id(), cpu_online_map); |
495 | } | 493 | } |
496 | 494 | ||