X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fx86_64%2Fkernel%2Fsmpboot.c;h=a7e2c3e95ea5940bcab4345bb500782875ba17af;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=4d9c47feb69c9de325fff1a4290cdaccf2337512;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 4d9c47feb..a7e2c3e95 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -55,15 +56,14 @@ /* Number of siblings per CPU package */ int smp_num_siblings = 1; -char phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ +/* Package ID of each logical CPU */ +u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; +EXPORT_SYMBOL(phys_proc_id); /* Bitmask of currently online CPUs */ cpumask_t cpu_online_map; -/* which logical CPU number maps to which CPU (physical APIC ID) */ -volatile char x86_cpu_to_apicid[NR_CPUS]; - -static cpumask_t cpu_callin_map; +cpumask_t cpu_callin_map; cpumask_t cpu_callout_map; static cpumask_t smp_commenced_mask; @@ -73,7 +73,7 @@ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; /* Set when the idlers are all forked */ int smp_threads_ready; -char cpu_sibling_map[NR_CPUS] __cacheline_aligned; +cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; /* * Trampoline 80x86 program as an array. @@ -390,16 +390,6 @@ void __init start_secondary(void) extern volatile unsigned long init_rsp; extern void (*initial_code)(void); -static struct task_struct * __init fork_by_hand(void) -{ - struct pt_regs regs; - /* - * don't care about the eip and regs settings since - * we'll never reschedule the forked task. - */ - return copy_process(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0, NULL, NULL); -} - #if APIC_DEBUG static inline void inquire_remote_apic(int apicid) { @@ -573,26 +563,17 @@ static void __init do_boot_cpu (int apicid) * We can't use kernel_thread since we must avoid to * reschedule the child. */ - idle = fork_by_hand(); + idle = fork_idle(cpu); if (IS_ERR(idle)) panic("failed fork for CPU %d", cpu); - wake_up_forked_process(idle); x86_cpu_to_apicid[cpu] = apicid; - /* - * We remove it from the pidhash and the runqueue - * once we got the process: - */ - init_idle(idle,cpu); - - unhash_process(idle); - cpu_pda[cpu].pcurrent = idle; start_rip = setup_trampoline(); init_rsp = idle->thread.rsp; - init_tss[cpu].rsp0 = init_rsp; + per_cpu(init_tss,cpu).rsp0 = init_rsp; initial_code = start_secondary; clear_ti_thread_flag(idle->thread_info, TIF_FORK); @@ -659,7 +640,7 @@ static void __init do_boot_cpu (int apicid) Dprintk("CPU has booted.\n"); } else { boot_error = 1; - if (*((volatile unsigned char *)phys_to_virt(8192)) + if (*((volatile unsigned char *)phys_to_virt(SMP_TRAMPOLINE_BASE)) == 0xA5) /* trampoline started but...? */ printk("Stuck ??\n"); @@ -675,10 +656,9 @@ static void __init do_boot_cpu (int apicid) cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ cpucount--; + x86_cpu_to_apicid[cpu] = BAD_APICID; + x86_cpu_to_log_apicid[cpu] = BAD_APICID; } - - /* mark "stuck" area as not stuck */ - *((volatile unsigned *)phys_to_virt(8192)) = 0; } cycles_t cacheflush_time; @@ -827,7 +807,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) if (apicid == boot_cpu_id || (apicid == BAD_APICID)) continue; - if (!cpu_isset(apicid, phys_cpu_present_map)) + if (!physid_isset(apicid, phys_cpu_present_map)) continue; if ((max_cpus >= 0) && (max_cpus <= cpucount+1)) continue; @@ -874,31 +854,38 @@ static void __init smp_boot_cpus(unsigned int max_cpus) } /* - * If Hyper-Threading is avaialble, construct cpu_sibling_map[], so - * that we can tell the sibling CPU efficiently. + * Construct cpu_sibling_map[], so that we can tell the + * sibling CPU efficiently. */ - if (cpu_has_ht && smp_num_siblings > 1) { - for (cpu = 0; cpu < NR_CPUS; cpu++) - cpu_sibling_map[cpu] = NO_PROC_ID; - - for (cpu = 0; cpu < NR_CPUS; cpu++) { - int i; - if (!cpu_isset(cpu, cpu_callout_map)) - continue; + for (cpu = 0; cpu < NR_CPUS; cpu++) + cpus_clear(cpu_sibling_map[cpu]); + + for (cpu = 0; cpu < NR_CPUS; cpu++) { + int siblings = 0; + int i; + if (!cpu_isset(cpu, cpu_callout_map)) + continue; + if (smp_num_siblings > 1) { for (i = 0; i < NR_CPUS; i++) { - if (i == cpu || !cpu_isset(i, cpu_callout_map)) + if (!cpu_isset(i, cpu_callout_map)) continue; if (phys_proc_id[cpu] == phys_proc_id[i]) { - cpu_sibling_map[cpu] = i; - break; + siblings++; + cpu_set(i, cpu_sibling_map[cpu]); } } - if (cpu_sibling_map[cpu] == (char)NO_PROC_ID) { - smp_num_siblings = 1; - printk(KERN_WARNING "WARNING: No sibling found for CPU %d.\n", cpu); - } + } else { + siblings++; + cpu_set(cpu, cpu_sibling_map[cpu]); } + + if (siblings != smp_num_siblings) { + printk(KERN_WARNING + "WARNING: %d siblings found for CPU%d, should be %d\n", + siblings, cpu, smp_num_siblings); + smp_num_siblings = siblings; + } } Dprintk("Boot done.\n"); @@ -963,6 +950,9 @@ int __devinit __cpu_up(unsigned int cpu) void __init smp_cpus_done(unsigned int max_cpus) { +#ifdef CONFIG_X86_IO_APIC + setup_ioapic_dest(); +#endif zap_low_mappings(); }