x86: integrate start_secondary
It now looks the same between architectures, so we merge it in smpboot.c. Minor differences goes inside an ifdef Signed-off-by: Glauber Costa <gcosta@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
cb3c8b9003
commit
bbc2ff6a91
|
@ -17,6 +17,7 @@
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
#include <asm/mtrr.h>
|
#include <asm/mtrr.h>
|
||||||
#include <asm/nmi.h>
|
#include <asm/nmi.h>
|
||||||
|
#include <asm/vmi.h>
|
||||||
#include <linux/mc146818rtc.h>
|
#include <linux/mc146818rtc.h>
|
||||||
|
|
||||||
#include <mach_apic.h>
|
#include <mach_apic.h>
|
||||||
|
@ -229,6 +230,90 @@ void __cpuinit smp_callin(void)
|
||||||
cpu_set(cpuid, cpu_callin_map);
|
cpu_set(cpuid, cpu_callin_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Activate a secondary processor.
|
||||||
|
*/
|
||||||
|
void __cpuinit start_secondary(void *unused)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Don't put *anything* before cpu_init(), SMP booting is too
|
||||||
|
* fragile that we want to limit the things done here to the
|
||||||
|
* most necessary things.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_VMI
|
||||||
|
vmi_bringup();
|
||||||
|
#endif
|
||||||
|
cpu_init();
|
||||||
|
preempt_disable();
|
||||||
|
smp_callin();
|
||||||
|
|
||||||
|
/* otherwise gcc will move up smp_processor_id before the cpu_init */
|
||||||
|
barrier();
|
||||||
|
/*
|
||||||
|
* Check TSC synchronization with the BP:
|
||||||
|
*/
|
||||||
|
check_tsc_sync_target();
|
||||||
|
|
||||||
|
if (nmi_watchdog == NMI_IO_APIC) {
|
||||||
|
disable_8259A_irq(0);
|
||||||
|
enable_NMI_through_LVT0();
|
||||||
|
enable_8259A_irq(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This must be done before setting cpu_online_map */
|
||||||
|
set_cpu_sibling_map(raw_smp_processor_id());
|
||||||
|
wmb();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to hold call_lock, so there is no inconsistency
|
||||||
|
* between the time smp_call_function() determines number of
|
||||||
|
* IPI recipients, and the time when the determination is made
|
||||||
|
* for which cpus receive the IPI. Holding this
|
||||||
|
* lock helps us to not include this cpu in a currently in progress
|
||||||
|
* smp_call_function().
|
||||||
|
*/
|
||||||
|
lock_ipi_call_lock();
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
spin_lock(&vector_lock);
|
||||||
|
|
||||||
|
/* Setup the per cpu irq handling data structures */
|
||||||
|
__setup_vector_irq(smp_processor_id());
|
||||||
|
/*
|
||||||
|
* Allow the master to continue.
|
||||||
|
*/
|
||||||
|
spin_unlock(&vector_lock);
|
||||||
|
#endif
|
||||||
|
cpu_set(smp_processor_id(), cpu_online_map);
|
||||||
|
unlock_ipi_call_lock();
|
||||||
|
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
|
||||||
|
|
||||||
|
setup_secondary_clock();
|
||||||
|
|
||||||
|
wmb();
|
||||||
|
cpu_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
/*
|
||||||
|
* Everything has been set up for the secondary
|
||||||
|
* CPUs - they just need to reload everything
|
||||||
|
* from the task structure
|
||||||
|
* This function must not return.
|
||||||
|
*/
|
||||||
|
void __devinit initialize_secondary(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We don't actually need to load the full TSS,
|
||||||
|
* basically just the stack pointer and the ip.
|
||||||
|
*/
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
"movl %0,%%esp\n\t"
|
||||||
|
"jmp *%1"
|
||||||
|
:
|
||||||
|
:"m" (current->thread.sp), "m" (current->thread.ip));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void __cpuinit smp_apply_quirks(struct cpuinfo_x86 *c)
|
static void __cpuinit smp_apply_quirks(struct cpuinfo_x86 *c)
|
||||||
{
|
{
|
||||||
|
@ -533,7 +618,6 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
|
||||||
}
|
}
|
||||||
#endif /* WAKE_SECONDARY_VIA_NMI */
|
#endif /* WAKE_SECONDARY_VIA_NMI */
|
||||||
|
|
||||||
extern void start_secondary(void *unused);
|
|
||||||
#ifdef WAKE_SECONDARY_VIA_INIT
|
#ifdef WAKE_SECONDARY_VIA_INIT
|
||||||
static int __devinit
|
static int __devinit
|
||||||
wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
|
wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
|
||||||
|
|
|
@ -80,81 +80,6 @@ extern void unmap_cpu_to_logical_apicid(int cpu);
|
||||||
/* State of each CPU. */
|
/* State of each CPU. */
|
||||||
DEFINE_PER_CPU(int, cpu_state) = { 0 };
|
DEFINE_PER_CPU(int, cpu_state) = { 0 };
|
||||||
|
|
||||||
extern void smp_callin(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Activate a secondary processor.
|
|
||||||
*/
|
|
||||||
void __cpuinit start_secondary(void *unused)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Don't put *anything* before cpu_init(), SMP booting is too
|
|
||||||
* fragile that we want to limit the things done here to the
|
|
||||||
* most necessary things.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_VMI
|
|
||||||
vmi_bringup();
|
|
||||||
#endif
|
|
||||||
cpu_init();
|
|
||||||
preempt_disable();
|
|
||||||
smp_callin();
|
|
||||||
|
|
||||||
/* otherwise gcc will move up smp_processor_id before the cpu_init */
|
|
||||||
barrier();
|
|
||||||
/*
|
|
||||||
* Check TSC synchronization with the BP:
|
|
||||||
*/
|
|
||||||
check_tsc_sync_target();
|
|
||||||
|
|
||||||
if (nmi_watchdog == NMI_IO_APIC) {
|
|
||||||
disable_8259A_irq(0);
|
|
||||||
enable_NMI_through_LVT0();
|
|
||||||
enable_8259A_irq(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This must be done before setting cpu_online_map */
|
|
||||||
set_cpu_sibling_map(raw_smp_processor_id());
|
|
||||||
wmb();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We need to hold call_lock, so there is no inconsistency
|
|
||||||
* between the time smp_call_function() determines number of
|
|
||||||
* IPI recipients, and the time when the determination is made
|
|
||||||
* for which cpus receive the IPI. Holding this
|
|
||||||
* lock helps us to not include this cpu in a currently in progress
|
|
||||||
* smp_call_function().
|
|
||||||
*/
|
|
||||||
lock_ipi_call_lock();
|
|
||||||
cpu_set(smp_processor_id(), cpu_online_map);
|
|
||||||
unlock_ipi_call_lock();
|
|
||||||
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
|
|
||||||
|
|
||||||
setup_secondary_clock();
|
|
||||||
|
|
||||||
wmb();
|
|
||||||
cpu_idle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Everything has been set up for the secondary
|
|
||||||
* CPUs - they just need to reload everything
|
|
||||||
* from the task structure
|
|
||||||
* This function must not return.
|
|
||||||
*/
|
|
||||||
void __devinit initialize_secondary(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We don't actually need to load the full TSS,
|
|
||||||
* basically just the stack pointer and the ip.
|
|
||||||
*/
|
|
||||||
|
|
||||||
asm volatile(
|
|
||||||
"movl %0,%%esp\n\t"
|
|
||||||
"jmp *%1"
|
|
||||||
:
|
|
||||||
:"m" (current->thread.sp),"m" (current->thread.ip));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
void cpu_exit_clear(void)
|
void cpu_exit_clear(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,69 +71,6 @@ int smp_threads_ready;
|
||||||
/* State of each CPU */
|
/* State of each CPU */
|
||||||
DEFINE_PER_CPU(int, cpu_state) = { 0 };
|
DEFINE_PER_CPU(int, cpu_state) = { 0 };
|
||||||
|
|
||||||
extern void smp_callin(void);
|
|
||||||
/*
|
|
||||||
* Setup code on secondary processor (after comming out of the trampoline)
|
|
||||||
*/
|
|
||||||
void __cpuinit start_secondary(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Dont put anything before smp_callin(), SMP
|
|
||||||
* booting is too fragile that we want to limit the
|
|
||||||
* things done here to the most necessary things.
|
|
||||||
*/
|
|
||||||
cpu_init();
|
|
||||||
preempt_disable();
|
|
||||||
smp_callin();
|
|
||||||
|
|
||||||
/* otherwise gcc will move up the smp_processor_id before the cpu_init */
|
|
||||||
barrier();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check TSC sync first:
|
|
||||||
*/
|
|
||||||
check_tsc_sync_target();
|
|
||||||
|
|
||||||
if (nmi_watchdog == NMI_IO_APIC) {
|
|
||||||
disable_8259A_irq(0);
|
|
||||||
enable_NMI_through_LVT0();
|
|
||||||
enable_8259A_irq(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The sibling maps must be set before turing the online map on for
|
|
||||||
* this cpu
|
|
||||||
*/
|
|
||||||
set_cpu_sibling_map(smp_processor_id());
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We need to hold call_lock, so there is no inconsistency
|
|
||||||
* between the time smp_call_function() determines number of
|
|
||||||
* IPI recipients, and the time when the determination is made
|
|
||||||
* for which cpus receive the IPI in genapic_flat.c. Holding this
|
|
||||||
* lock helps us to not include this cpu in a currently in progress
|
|
||||||
* smp_call_function().
|
|
||||||
*/
|
|
||||||
lock_ipi_call_lock();
|
|
||||||
spin_lock(&vector_lock);
|
|
||||||
|
|
||||||
/* Setup the per cpu irq handling data structures */
|
|
||||||
__setup_vector_irq(smp_processor_id());
|
|
||||||
/*
|
|
||||||
* Allow the master to continue.
|
|
||||||
*/
|
|
||||||
spin_unlock(&vector_lock);
|
|
||||||
cpu_set(smp_processor_id(), cpu_online_map);
|
|
||||||
unlock_ipi_call_lock();
|
|
||||||
|
|
||||||
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
|
|
||||||
|
|
||||||
setup_secondary_clock();
|
|
||||||
|
|
||||||
wmb();
|
|
||||||
cpu_idle();
|
|
||||||
}
|
|
||||||
|
|
||||||
cycles_t cacheflush_time;
|
cycles_t cacheflush_time;
|
||||||
unsigned long cache_decay_ticks;
|
unsigned long cache_decay_ticks;
|
||||||
|
|
||||||
|
|
Reference in New Issue