Commit a8ab26fe authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86_64: Switch SMP bootup over to new CPU hotplug state machine

This will allow hotplug CPU in the future and in general cleans up a lot of
crufty code.  It also should plug some races that the old hackish way
introduces.  Remove one old race workaround in NMI watchdog setup that is not
needed anymore.

I removed the old total sum of bogomips reporting code.  The brag value of
BogoMips has been greatly devalued in the last years on the open market.

Real CPU hotplug will need some more work, but the infrastructure for it is
there now.

One drawback: the new TSC sync algorithm is less accurate than before.  The
old way of zeroing TSCs is too intrusive to do later.  Instead the TSC of the
BP is duplicated now, which is less accurate.

akpm:

- sync_tsc_bp_init seems to have the sense of `init' inverted.

- SPIN_LOCK_UNLOCKED is deprecated - use DEFINE_SPINLOCK.

Cc: <rusty@rustcorp.com.au>
Cc: <mingo@elte.hu>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ebfcaa96
...@@ -130,12 +130,6 @@ int __init check_nmi_watchdog (void) ...@@ -130,12 +130,6 @@ int __init check_nmi_watchdog (void)
mdelay((10*1000)/nmi_hz); // wait 10 ticks mdelay((10*1000)/nmi_hz); // wait 10 ticks
for (cpu = 0; cpu < NR_CPUS; cpu++) { for (cpu = 0; cpu < NR_CPUS; cpu++) {
#ifdef CONFIG_SMP
/* Check cpu_callin_map here because that is set
after the timer is started. */
if (!cpu_isset(cpu, cpu_callin_map))
continue;
#endif
if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) { if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) {
printk("CPU#%d: NMI appears to be stuck (%d)!\n", printk("CPU#%d: NMI appears to be stuck (%d)!\n",
cpu, cpu,
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <asm/mach_apic.h> #include <asm/mach_apic.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/proto.h> #include <asm/proto.h>
#include <asm/apicdef.h>
/* /*
* Smarter SMP flushing macros. * Smarter SMP flushing macros.
...@@ -413,3 +414,27 @@ asmlinkage void smp_call_function_interrupt(void) ...@@ -413,3 +414,27 @@ asmlinkage void smp_call_function_interrupt(void)
atomic_inc(&call_data->finished); atomic_inc(&call_data->finished);
} }
} }
int safe_smp_processor_id(void)
{
int apicid, i;
if (disable_apic)
return 0;
apicid = hard_smp_processor_id();
if (x86_cpu_to_apicid[apicid] == apicid)
return apicid;
for (i = 0; i < NR_CPUS; ++i) {
if (x86_cpu_to_apicid[i] == apicid)
return i;
}
/* No entries in x86_cpu_to_apicid? Either no MPS|ACPI,
* or called too early. Either way, we must be CPU 0. */
if (x86_cpu_to_apicid[0] == BAD_APICID)
return 0;
return 0; /* Should not happen */
}
This diff is collapsed.
...@@ -916,9 +916,16 @@ void __init time_init(void) ...@@ -916,9 +916,16 @@ void __init time_init(void)
setup_irq(0, &irq0); setup_irq(0, &irq0);
set_cyc2ns_scale(cpu_khz / 1000); set_cyc2ns_scale(cpu_khz / 1000);
#ifndef CONFIG_SMP
time_init_gtod();
#endif
} }
void __init time_init_smp(void) /*
* Decide after all CPUs are booted what mode gettimeofday should use.
*/
void __init time_init_gtod(void)
{ {
char *timetype; char *timetype;
......
...@@ -163,6 +163,7 @@ extern inline unsigned int cpuid_edx(unsigned int op) ...@@ -163,6 +163,7 @@ extern inline unsigned int cpuid_edx(unsigned int op)
#define EFER_NX (1<<_EFER_NX) #define EFER_NX (1<<_EFER_NX)
/* Intel MSRs. Some also available on other CPUs */ /* Intel MSRs. Some also available on other CPUs */
#define MSR_IA32_TSC 0x10
#define MSR_IA32_PLATFORM_ID 0x17 #define MSR_IA32_PLATFORM_ID 0x17
#define MSR_IA32_PERFCTR0 0xc1 #define MSR_IA32_PERFCTR0 0xc1
......
...@@ -29,7 +29,7 @@ extern void config_acpi_tables(void); ...@@ -29,7 +29,7 @@ extern void config_acpi_tables(void);
extern void ia32_syscall(void); extern void ia32_syscall(void);
extern void iommu_hole_init(void); extern void iommu_hole_init(void);
extern void time_init_smp(void); extern void time_init_gtod(void);
extern void do_softirq_thunk(void); extern void do_softirq_thunk(void);
......
...@@ -31,12 +31,16 @@ extern int disable_apic; ...@@ -31,12 +31,16 @@ extern int disable_apic;
struct pt_regs; struct pt_regs;
extern cpumask_t cpu_present_mask;
extern cpumask_t cpu_possible_map;
extern cpumask_t cpu_online_map;
extern cpumask_t cpu_callout_map;
/* /*
* Private routines/data * Private routines/data
*/ */
extern void smp_alloc_memory(void); extern void smp_alloc_memory(void);
extern cpumask_t cpu_online_map;
extern volatile unsigned long smp_invalidate_needed; extern volatile unsigned long smp_invalidate_needed;
extern int pic_mode; extern int pic_mode;
extern int smp_num_siblings; extern int smp_num_siblings;
...@@ -44,7 +48,6 @@ extern void smp_flush_tlb(void); ...@@ -44,7 +48,6 @@ extern void smp_flush_tlb(void);
extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
extern void smp_send_reschedule(int cpu); extern void smp_send_reschedule(int cpu);
extern void smp_invalidate_rcv(void); /* Process an NMI */ extern void smp_invalidate_rcv(void); /* Process an NMI */
extern void (*mtrr_hook) (void);
extern void zap_low_mappings(void); extern void zap_low_mappings(void);
void smp_stop_cpu(void); void smp_stop_cpu(void);
extern cpumask_t cpu_sibling_map[NR_CPUS]; extern cpumask_t cpu_sibling_map[NR_CPUS];
...@@ -60,10 +63,6 @@ extern u8 cpu_core_id[NR_CPUS]; ...@@ -60,10 +63,6 @@ extern u8 cpu_core_id[NR_CPUS];
* compresses data structures. * compresses data structures.
*/ */
extern cpumask_t cpu_callout_map;
extern cpumask_t cpu_callin_map;
#define cpu_possible_map cpu_callout_map
static inline int num_booting_cpus(void) static inline int num_booting_cpus(void)
{ {
return cpus_weight(cpu_callout_map); return cpus_weight(cpu_callout_map);
...@@ -77,7 +76,7 @@ extern __inline int hard_smp_processor_id(void) ...@@ -77,7 +76,7 @@ extern __inline int hard_smp_processor_id(void)
return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID)); return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID));
} }
#define safe_smp_processor_id() (disable_apic ? 0 : x86_apicid_to_cpu(hard_smp_processor_id())) extern int safe_smp_processor_id(void);
#endif /* !ASSEMBLY */ #endif /* !ASSEMBLY */
...@@ -99,22 +98,6 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) ...@@ -99,22 +98,6 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
return cpus_addr(cpumask)[0]; return cpus_addr(cpumask)[0];
} }
static inline int x86_apicid_to_cpu(u8 apicid)
{
int i;
for (i = 0; i < NR_CPUS; ++i)
if (x86_cpu_to_apicid[i] == apicid)
return i;
/* No entries in x86_cpu_to_apicid? Either no MPS|ACPI,
* or called too early. Either way, we must be CPU 0. */
if (x86_cpu_to_apicid[0] == BAD_APICID)
return 0;
return -1;
}
static inline int cpu_present_to_apicid(int mps_cpu) static inline int cpu_present_to_apicid(int mps_cpu)
{ {
if (mps_cpu < NR_CPUS) if (mps_cpu < NR_CPUS)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment