diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 0133a952d11f..2ff0bbcd5bd1 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -749,6 +749,14 @@ static void __cpuinit do_fork_idle(struct work_struct *work) | |||
749 | } | 749 | } |
750 | 750 | ||
751 | #ifdef CONFIG_X86_64 | 751 | #ifdef CONFIG_X86_64 |
752 | |||
753 | /* __ref because it's safe to call free_bootmem when after_bootmem == 0. */ | ||
754 | static void __ref free_bootmem_pda(struct x8664_pda *oldpda) | ||
755 | { | ||
756 | if (!after_bootmem) | ||
757 | free_bootmem((unsigned long)oldpda, sizeof(*oldpda)); | ||
758 | } | ||
759 | |||
752 | /* | 760 | /* |
753 | * Allocate node local memory for the AP pda. | 761 | * Allocate node local memory for the AP pda. |
754 | * | 762 | * |
@@ -777,8 +785,7 @@ int __cpuinit get_local_pda(int cpu) | |||
777 | 785 | ||
778 | if (oldpda) { | 786 | if (oldpda) { |
779 | memcpy(newpda, oldpda, size); | 787 | memcpy(newpda, oldpda, size); |
780 | if (!after_bootmem) | 788 | free_bootmem_pda(oldpda); |
781 | free_bootmem((unsigned long)oldpda, size); | ||
782 | } | 789 | } |
783 | 790 | ||
784 | newpda->in_bootmem = 0; | 791 | newpda->in_bootmem = 0; |
@@ -987,17 +994,7 @@ int __cpuinit native_cpu_up(unsigned int cpu) | |||
987 | flush_tlb_all(); | 994 | flush_tlb_all(); |
988 | low_mappings = 1; | 995 | low_mappings = 1; |
989 | 996 | ||
990 | #ifdef CONFIG_X86_PC | ||
991 | if (def_to_bigsmp && apicid > 8) { | ||
992 | printk(KERN_WARNING | ||
993 | "More than 8 CPUs detected - skipping them.\n" | ||
994 | "Use CONFIG_X86_GENERICARCH and CONFIG_X86_BIGSMP.\n"); | ||
995 | err = -1; | ||
996 | } else | ||
997 | err = do_boot_cpu(apicid, cpu); | ||
998 | #else | ||
999 | err = do_boot_cpu(apicid, cpu); | 997 | err = do_boot_cpu(apicid, cpu); |
1000 | #endif | ||
1001 | 998 | ||
1002 | zap_low_mappings(); | 999 | zap_low_mappings(); |
1003 | low_mappings = 0; | 1000 | low_mappings = 0; |
@@ -1051,6 +1048,34 @@ static __init void disable_smp(void) | |||
1051 | static int __init smp_sanity_check(unsigned max_cpus) | 1048 | static int __init smp_sanity_check(unsigned max_cpus) |
1052 | { | 1049 | { |
1053 | preempt_disable(); | 1050 | preempt_disable(); |
1051 | |||
1052 | #if defined(CONFIG_X86_PC) && defined(CONFIG_X86_32) | ||
1053 | if (def_to_bigsmp && nr_cpu_ids > 8) { | ||
1054 | unsigned int cpu; | ||
1055 | unsigned nr; | ||
1056 | |||
1057 | printk(KERN_WARNING | ||
1058 | "More than 8 CPUs detected - skipping them.\n" | ||
1059 | "Use CONFIG_X86_GENERICARCH and CONFIG_X86_BIGSMP.\n"); | ||
1060 | |||
1061 | nr = 0; | ||
1062 | for_each_present_cpu(cpu) { | ||
1063 | if (nr >= 8) | ||
1064 | cpu_clear(cpu, cpu_present_map); | ||
1065 | nr++; | ||
1066 | } | ||
1067 | |||
1068 | nr = 0; | ||
1069 | for_each_possible_cpu(cpu) { | ||
1070 | if (nr >= 8) | ||
1071 | cpu_clear(cpu, cpu_possible_map); | ||
1072 | nr++; | ||
1073 | } | ||
1074 | |||
1075 | nr_cpu_ids = 8; | ||
1076 | } | ||
1077 | #endif | ||
1078 | |||
1054 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { | 1079 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { |
1055 | printk(KERN_WARNING "weird, boot CPU (#%d) not listed" | 1080 | printk(KERN_WARNING "weird, boot CPU (#%d) not listed" |
1056 | "by the BIOS.\n", hard_smp_processor_id()); | 1081 | "by the BIOS.\n", hard_smp_processor_id()); |
@@ -1196,6 +1221,9 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
1196 | printk(KERN_INFO "CPU%d: ", 0); | 1221 | printk(KERN_INFO "CPU%d: ", 0); |
1197 | print_cpu_info(&cpu_data(0)); | 1222 | print_cpu_info(&cpu_data(0)); |
1198 | setup_boot_clock(); | 1223 | setup_boot_clock(); |
1224 | |||
1225 | if (is_uv_system()) | ||
1226 | uv_system_init(); | ||
1199 | out: | 1227 | out: |
1200 | preempt_enable(); | 1228 | preempt_enable(); |
1201 | } | 1229 | } |
@@ -1285,16 +1313,13 @@ __init void prefill_possible_map(void) | |||
1285 | if (!num_processors) | 1313 | if (!num_processors) |
1286 | num_processors = 1; | 1314 | num_processors = 1; |
1287 | 1315 | ||
1288 | #ifdef CONFIG_HOTPLUG_CPU | ||
1289 | if (additional_cpus == -1) { | 1316 | if (additional_cpus == -1) { |
1290 | if (disabled_cpus > 0) | 1317 | if (disabled_cpus > 0) |
1291 | additional_cpus = disabled_cpus; | 1318 | additional_cpus = disabled_cpus; |
1292 | else | 1319 | else |
1293 | additional_cpus = 0; | 1320 | additional_cpus = 0; |
1294 | } | 1321 | } |
1295 | #else | 1322 | |
1296 | additional_cpus = 0; | ||
1297 | #endif | ||
1298 | possible = num_processors + additional_cpus; | 1323 | possible = num_processors + additional_cpus; |
1299 | if (possible > NR_CPUS) | 1324 | if (possible > NR_CPUS) |
1300 | possible = NR_CPUS; | 1325 | possible = NR_CPUS; |
@@ -1386,17 +1411,3 @@ void __cpu_die(unsigned int cpu) | |||
1386 | BUG(); | 1411 | BUG(); |
1387 | } | 1412 | } |
1388 | #endif | 1413 | #endif |
1389 | |||
1390 | /* | ||
1391 | * If the BIOS enumerates physical processors before logical, | ||
1392 | * maxcpus=N at enumeration-time can be used to disable HT. | ||
1393 | */ | ||
1394 | static int __init parse_maxcpus(char *arg) | ||
1395 | { | ||
1396 | extern unsigned int maxcpus; | ||
1397 | |||
1398 | if (arg) | ||
1399 | maxcpus = simple_strtoul(arg, NULL, 0); | ||
1400 | return 0; | ||
1401 | } | ||
1402 | early_param("maxcpus", parse_maxcpus); | ||