diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 77 | 
1 files changed, 57 insertions, 20 deletions
| diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 9056f7e272c0..76b6f50978f7 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -52,6 +52,7 @@ | |||
| 52 | #include <asm/desc.h> | 52 | #include <asm/desc.h> | 
| 53 | #include <asm/nmi.h> | 53 | #include <asm/nmi.h> | 
| 54 | #include <asm/irq.h> | 54 | #include <asm/irq.h> | 
| 55 | #include <asm/idle.h> | ||
| 55 | #include <asm/smp.h> | 56 | #include <asm/smp.h> | 
| 56 | #include <asm/trampoline.h> | 57 | #include <asm/trampoline.h> | 
| 57 | #include <asm/cpu.h> | 58 | #include <asm/cpu.h> | 
| @@ -1344,25 +1345,9 @@ static void __ref remove_cpu_from_maps(int cpu) | |||
| 1344 | numa_remove_cpu(cpu); | 1345 | numa_remove_cpu(cpu); | 
| 1345 | } | 1346 | } | 
| 1346 | 1347 | ||
| 1347 | int __cpu_disable(void) | 1348 | void cpu_disable_common(void) | 
| 1348 | { | 1349 | { | 
| 1349 | int cpu = smp_processor_id(); | 1350 | int cpu = smp_processor_id(); | 
| 1350 | |||
| 1351 | /* | ||
| 1352 | * Perhaps use cpufreq to drop frequency, but that could go | ||
| 1353 | * into generic code. | ||
| 1354 | * | ||
| 1355 | * We won't take down the boot processor on i386 due to some | ||
| 1356 | * interrupts only being able to be serviced by the BSP. | ||
| 1357 | * Especially so if we're not using an IOAPIC -zwane | ||
| 1358 | */ | ||
| 1359 | if (cpu == 0) | ||
| 1360 | return -EBUSY; | ||
| 1361 | |||
| 1362 | if (nmi_watchdog == NMI_LOCAL_APIC) | ||
| 1363 | stop_apic_nmi_watchdog(NULL); | ||
| 1364 | clear_local_APIC(); | ||
| 1365 | |||
| 1366 | /* | 1351 | /* | 
| 1367 | * HACK: | 1352 | * HACK: | 
| 1368 | * Allow any queued timer interrupts to get serviced | 1353 | * Allow any queued timer interrupts to get serviced | 
| @@ -1380,10 +1365,32 @@ int __cpu_disable(void) | |||
| 1380 | remove_cpu_from_maps(cpu); | 1365 | remove_cpu_from_maps(cpu); | 
| 1381 | unlock_vector_lock(); | 1366 | unlock_vector_lock(); | 
| 1382 | fixup_irqs(cpu_online_map); | 1367 | fixup_irqs(cpu_online_map); | 
| 1368 | } | ||
| 1369 | |||
| 1370 | int native_cpu_disable(void) | ||
| 1371 | { | ||
| 1372 | int cpu = smp_processor_id(); | ||
| 1373 | |||
| 1374 | /* | ||
| 1375 | * Perhaps use cpufreq to drop frequency, but that could go | ||
| 1376 | * into generic code. | ||
| 1377 | * | ||
| 1378 | * We won't take down the boot processor on i386 due to some | ||
| 1379 | * interrupts only being able to be serviced by the BSP. | ||
| 1380 | * Especially so if we're not using an IOAPIC -zwane | ||
| 1381 | */ | ||
| 1382 | if (cpu == 0) | ||
| 1383 | return -EBUSY; | ||
| 1384 | |||
| 1385 | if (nmi_watchdog == NMI_LOCAL_APIC) | ||
| 1386 | stop_apic_nmi_watchdog(NULL); | ||
| 1387 | clear_local_APIC(); | ||
| 1388 | |||
| 1389 | cpu_disable_common(); | ||
| 1383 | return 0; | 1390 | return 0; | 
| 1384 | } | 1391 | } | 
| 1385 | 1392 | ||
| 1386 | void __cpu_die(unsigned int cpu) | 1393 | void native_cpu_die(unsigned int cpu) | 
| 1387 | { | 1394 | { | 
| 1388 | /* We don't do anything here: idle task is faking death itself. */ | 1395 | /* We don't do anything here: idle task is faking death itself. */ | 
| 1389 | unsigned int i; | 1396 | unsigned int i; | 
| @@ -1400,15 +1407,45 @@ void __cpu_die(unsigned int cpu) | |||
| 1400 | } | 1407 | } | 
| 1401 | printk(KERN_ERR "CPU %u didn't die...\n", cpu); | 1408 | printk(KERN_ERR "CPU %u didn't die...\n", cpu); | 
| 1402 | } | 1409 | } | 
| 1410 | |||
| 1411 | void play_dead_common(void) | ||
| 1412 | { | ||
| 1413 | idle_task_exit(); | ||
| 1414 | reset_lazy_tlbstate(); | ||
| 1415 | irq_ctx_exit(raw_smp_processor_id()); | ||
| 1416 | c1e_remove_cpu(raw_smp_processor_id()); | ||
| 1417 | |||
| 1418 | mb(); | ||
| 1419 | /* Ack it */ | ||
| 1420 | __get_cpu_var(cpu_state) = CPU_DEAD; | ||
| 1421 | |||
| 1422 | /* | ||
| 1423 | * With physical CPU hotplug, we should halt the cpu | ||
| 1424 | */ | ||
| 1425 | local_irq_disable(); | ||
| 1426 | } | ||
| 1427 | |||
| 1428 | void native_play_dead(void) | ||
| 1429 | { | ||
| 1430 | play_dead_common(); | ||
| 1431 | wbinvd_halt(); | ||
| 1432 | } | ||
| 1433 | |||
| 1403 | #else /* ... !CONFIG_HOTPLUG_CPU */ | 1434 | #else /* ... !CONFIG_HOTPLUG_CPU */ | 
| 1404 | int __cpu_disable(void) | 1435 | int native_cpu_disable(void) | 
| 1405 | { | 1436 | { | 
| 1406 | return -ENOSYS; | 1437 | return -ENOSYS; | 
| 1407 | } | 1438 | } | 
| 1408 | 1439 | ||
| 1409 | void __cpu_die(unsigned int cpu) | 1440 | void native_cpu_die(unsigned int cpu) | 
| 1410 | { | 1441 | { | 
| 1411 | /* We said "no" in __cpu_disable */ | 1442 | /* We said "no" in __cpu_disable */ | 
| 1412 | BUG(); | 1443 | BUG(); | 
| 1413 | } | 1444 | } | 
| 1445 | |||
| 1446 | void native_play_dead(void) | ||
| 1447 | { | ||
| 1448 | BUG(); | ||
| 1449 | } | ||
| 1450 | |||
| 1414 | #endif | 1451 | #endif | 
