diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-08-20 05:52:15 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-08-20 05:52:15 -0400 |
commit | 7393423dd9b5790a3115873be355e9fc862bce8f (patch) | |
tree | fc83214602c8ce41dc06d5c8e21deada679521f7 /arch/x86/kernel/smpboot.c | |
parent | 8df9676d6402563da91427e8d9f2da8a4598aede (diff) | |
parent | 1fca25427482387689fa27594c992a961d98768f (diff) |
Merge branch 'linus' into x86/cleanups
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 65 |
1 files changed, 46 insertions, 19 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index d5e19c362046..18a2350deacd 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -326,12 +326,16 @@ static void __cpuinit start_secondary(void *unused) | |||
326 | * for which cpus receive the IPI. Holding this | 326 | * for which cpus receive the IPI. Holding this |
327 | * lock helps us to not include this cpu in a currently in progress | 327 | * lock helps us to not include this cpu in a currently in progress |
328 | * smp_call_function(). | 328 | * smp_call_function(). |
329 | * | ||
330 | * We need to hold vector_lock so there the set of online cpus | ||
331 | * does not change while we are assigning vectors to cpus. Holding | ||
332 | * this lock ensures we don't half assign or remove an irq from a cpu. | ||
329 | */ | 333 | */ |
330 | ipi_call_lock_irq(); | 334 | ipi_call_lock_irq(); |
331 | #ifdef CONFIG_X86_IO_APIC | 335 | lock_vector_lock(); |
332 | setup_vector_irq(smp_processor_id()); | 336 | __setup_vector_irq(smp_processor_id()); |
333 | #endif | ||
334 | cpu_set(smp_processor_id(), cpu_online_map); | 337 | cpu_set(smp_processor_id(), cpu_online_map); |
338 | unlock_vector_lock(); | ||
335 | ipi_call_unlock_irq(); | 339 | ipi_call_unlock_irq(); |
336 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | 340 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; |
337 | 341 | ||
@@ -752,6 +756,14 @@ static void __cpuinit do_fork_idle(struct work_struct *work) | |||
752 | } | 756 | } |
753 | 757 | ||
754 | #ifdef CONFIG_X86_64 | 758 | #ifdef CONFIG_X86_64 |
759 | |||
760 | /* __ref because it's safe to call free_bootmem when after_bootmem == 0. */ | ||
761 | static void __ref free_bootmem_pda(struct x8664_pda *oldpda) | ||
762 | { | ||
763 | if (!after_bootmem) | ||
764 | free_bootmem((unsigned long)oldpda, sizeof(*oldpda)); | ||
765 | } | ||
766 | |||
755 | /* | 767 | /* |
756 | * Allocate node local memory for the AP pda. | 768 | * Allocate node local memory for the AP pda. |
757 | * | 769 | * |
@@ -780,8 +792,7 @@ int __cpuinit get_local_pda(int cpu) | |||
780 | 792 | ||
781 | if (oldpda) { | 793 | if (oldpda) { |
782 | memcpy(newpda, oldpda, size); | 794 | memcpy(newpda, oldpda, size); |
783 | if (!after_bootmem) | 795 | free_bootmem_pda(oldpda); |
784 | free_bootmem((unsigned long)oldpda, size); | ||
785 | } | 796 | } |
786 | 797 | ||
787 | newpda->in_bootmem = 0; | 798 | newpda->in_bootmem = 0; |
@@ -1044,6 +1055,34 @@ static __init void disable_smp(void) | |||
1044 | static int __init smp_sanity_check(unsigned max_cpus) | 1055 | static int __init smp_sanity_check(unsigned max_cpus) |
1045 | { | 1056 | { |
1046 | preempt_disable(); | 1057 | preempt_disable(); |
1058 | |||
1059 | #if defined(CONFIG_X86_PC) && defined(CONFIG_X86_32) | ||
1060 | if (def_to_bigsmp && nr_cpu_ids > 8) { | ||
1061 | unsigned int cpu; | ||
1062 | unsigned nr; | ||
1063 | |||
1064 | printk(KERN_WARNING | ||
1065 | "More than 8 CPUs detected - skipping them.\n" | ||
1066 | "Use CONFIG_X86_GENERICARCH and CONFIG_X86_BIGSMP.\n"); | ||
1067 | |||
1068 | nr = 0; | ||
1069 | for_each_present_cpu(cpu) { | ||
1070 | if (nr >= 8) | ||
1071 | cpu_clear(cpu, cpu_present_map); | ||
1072 | nr++; | ||
1073 | } | ||
1074 | |||
1075 | nr = 0; | ||
1076 | for_each_possible_cpu(cpu) { | ||
1077 | if (nr >= 8) | ||
1078 | cpu_clear(cpu, cpu_possible_map); | ||
1079 | nr++; | ||
1080 | } | ||
1081 | |||
1082 | nr_cpu_ids = 8; | ||
1083 | } | ||
1084 | #endif | ||
1085 | |||
1047 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { | 1086 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { |
1048 | printk(KERN_WARNING "weird, boot CPU (#%d) not listed" | 1087 | printk(KERN_WARNING "weird, boot CPU (#%d) not listed" |
1049 | "by the BIOS.\n", hard_smp_processor_id()); | 1088 | "by the BIOS.\n", hard_smp_processor_id()); |
@@ -1333,7 +1372,9 @@ int __cpu_disable(void) | |||
1333 | remove_siblinginfo(cpu); | 1372 | remove_siblinginfo(cpu); |
1334 | 1373 | ||
1335 | /* It's now safe to remove this processor from the online map */ | 1374 | /* It's now safe to remove this processor from the online map */ |
1375 | lock_vector_lock(); | ||
1336 | remove_cpu_from_maps(cpu); | 1376 | remove_cpu_from_maps(cpu); |
1377 | unlock_vector_lock(); | ||
1337 | fixup_irqs(cpu_online_map); | 1378 | fixup_irqs(cpu_online_map); |
1338 | return 0; | 1379 | return 0; |
1339 | } | 1380 | } |
@@ -1367,17 +1408,3 @@ void __cpu_die(unsigned int cpu) | |||
1367 | BUG(); | 1408 | BUG(); |
1368 | } | 1409 | } |
1369 | #endif | 1410 | #endif |
1370 | |||
1371 | /* | ||
1372 | * If the BIOS enumerates physical processors before logical, | ||
1373 | * maxcpus=N at enumeration-time can be used to disable HT. | ||
1374 | */ | ||
1375 | static int __init parse_maxcpus(char *arg) | ||
1376 | { | ||
1377 | extern unsigned int maxcpus; | ||
1378 | |||
1379 | if (arg) | ||
1380 | maxcpus = simple_strtoul(arg, NULL, 0); | ||
1381 | return 0; | ||
1382 | } | ||
1383 | early_param("maxcpus", parse_maxcpus); | ||