upgrade to fedora-2.6.12-1.1398.FC4 + vserver 2.0.rc7
[linux-2.6.git] / arch / i386 / kernel / smpboot.c
index 016a070..1ce7180 100644 (file)
@@ -61,11 +61,14 @@ static int __initdata smp_b_stepping;
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
 int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
+EXPORT_SYMBOL(phys_proc_id);
+int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
+EXPORT_SYMBOL(cpu_core_id);
 
 /* bitmap of online cpus */
 cpumask_t cpu_online_map;
 
-static cpumask_t cpu_callin_map;
+cpumask_t cpu_callin_map;
 cpumask_t cpu_callout_map;
 static cpumask_t smp_commenced_mask;
 
@@ -76,9 +79,6 @@ u8 x86_cpu_to_apicid[NR_CPUS] =
                        { [0 ... NR_CPUS-1] = 0xff };
 EXPORT_SYMBOL(x86_cpu_to_apicid);
 
-/* Set when the idlers are all forked */
-int smp_threads_ready;
-
 /*
  * Trampoline 80x86 program as an array.
  */
@@ -88,6 +88,8 @@ extern unsigned char trampoline_end  [];
 static unsigned char *trampoline_base;
 static int trampoline_exec;
 
+static void map_cpu_to_logical_apicid(void);
+
 /*
  * Currently trivial. Write the real->protected mode
  * bootstrap into the page concerned. The caller
@@ -318,7 +320,7 @@ extern void calibrate_delay(void);
 
 static atomic_t init_deasserted;
 
-void __init smp_callin(void)
+static void __init smp_callin(void)
 {
        int cpuid, phys_id;
        unsigned long timeout;
@@ -382,8 +384,6 @@ void __init smp_callin(void)
        setup_local_APIC();
        map_cpu_to_logical_apicid();
 
-       local_irq_enable();
-
        /*
         * Get our bogomips.
         */
@@ -396,7 +396,7 @@ void __init smp_callin(void)
        smp_store_cpu_info(cpuid);
 
        disable_APIC_timer();
-       local_irq_disable();
+
        /*
         * Allow the master to continue.
         */
@@ -409,14 +409,12 @@ void __init smp_callin(void)
                synchronize_tsc_ap();
 }
 
-int cpucount;
-
-extern int cpu_idle(void);
+static int cpucount;
 
 /*
  * Activate a secondary processor.
  */
-int __init start_secondary(void *unused)
+static void __init start_secondary(void *unused)
 {
        /*
         * Dont put anything before smp_callin(), SMP
@@ -440,8 +438,12 @@ int __init start_secondary(void *unused)
         */
        local_flush_tlb();
        cpu_set(smp_processor_id(), cpu_online_map);
+
+       /* We can take interrupts now: we're officially "up". */
+       local_irq_enable();
+
        wmb();
-       return cpu_idle();
+       cpu_idle();
 }
 
 /*
@@ -505,7 +507,7 @@ static inline void unmap_cpu_to_node(int cpu)
 
 u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
 
-void map_cpu_to_logical_apicid(void)
+static void map_cpu_to_logical_apicid(void)
 {
        int cpu = smp_processor_id();
        int apicid = logical_smp_processor_id();
@@ -514,7 +516,7 @@ void map_cpu_to_logical_apicid(void)
        map_cpu_to_node(cpu, apicid_to_node(apicid));
 }
 
-void unmap_cpu_to_logical_apicid(int cpu)
+static void unmap_cpu_to_logical_apicid(int cpu)
 {
        cpu_2_logical_apicid[cpu] = BAD_APICID;
        unmap_cpu_to_node(cpu);
@@ -846,9 +848,6 @@ static int __init do_boot_cpu(int apicid)
        return boot_error;
 }
 
-cycles_t cacheflush_time;
-unsigned long cache_decay_ticks;
-
 static void smp_tune_scheduling (void)
 {
        unsigned long cachesize;       /* kB   */
@@ -869,7 +868,6 @@ static void smp_tune_scheduling (void)
                 * this basically disables processor-affinity
                 * scheduling on SMP without a TSC.
                 */
-               cacheflush_time = 0;
                return;
        } else {
                cachesize = boot_cpu_data.x86_cache_size;
@@ -877,17 +875,7 @@ static void smp_tune_scheduling (void)
                        cachesize = 16; /* Pentiums, 2x8kB cache */
                        bandwidth = 100;
                }
-
-               cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth;
        }
-
-       cache_decay_ticks = (long)cacheflush_time/cpu_khz + 1;
-
-       printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n",
-               (long)cacheflush_time/(cpu_khz/1000),
-               ((long)cacheflush_time*100/(cpu_khz/1000)) % 100);
-       printk("task migration cache decay timeout: %ld msecs.\n",
-               cache_decay_ticks);
 }
 
 /*
@@ -899,6 +887,8 @@ static int boot_cpu_logical_apicid;
 void *xquad_portio;
 
 cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
+cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_core_map);
 
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
@@ -921,6 +911,9 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        cpus_clear(cpu_sibling_map[0]);
        cpu_set(0, cpu_sibling_map[0]);
 
+       cpus_clear(cpu_core_map[0]);
+       cpu_set(0, cpu_core_map[0]);
+
        /*
         * If we couldn't find an SMP configuration at boot time,
         * get out of here now!
@@ -933,6 +926,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                        printk(KERN_NOTICE "Local APIC not detected."
                                           " Using dummy APIC emulation.\n");
                map_cpu_to_logical_apicid();
+               cpu_set(0, cpu_sibling_map[0]);
+               cpu_set(0, cpu_core_map[0]);
                return;
        }
 
@@ -956,6 +951,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
                smpboot_clear_io_apic_irqs();
                phys_cpu_present_map = physid_mask_of_physid(0);
+               cpu_set(0, cpu_sibling_map[0]);
+               cpu_set(0, cpu_core_map[0]);
                return;
        }
 
@@ -969,6 +966,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
                smpboot_clear_io_apic_irqs();
                phys_cpu_present_map = physid_mask_of_physid(0);
+               cpu_set(0, cpu_sibling_map[0]);
+               cpu_set(0, cpu_core_map[0]);
                return;
        }
 
@@ -1024,8 +1023,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        printk(KERN_INFO
                "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
                cpucount+1,
-               bogosum/(500000/HZ),
-               (bogosum/(5000/HZ))%100);
+               HZ*(bogosum >> 3)/62500,
+               (HZ*(bogosum >> 3)/625) % 100);
        
        Dprintk("Before bogocount - setting activated=1.\n");
 
@@ -1049,10 +1048,13 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
         * construct cpu_sibling_map[], so that we can tell sibling CPUs
         * efficiently.
         */
-       for (cpu = 0; cpu < NR_CPUS; cpu++)
+       for (cpu = 0; cpu < NR_CPUS; cpu++) {
                cpus_clear(cpu_sibling_map[cpu]);
+               cpus_clear(cpu_core_map[cpu]);
+       }
 
        for (cpu = 0; cpu < NR_CPUS; cpu++) {
+               struct cpuinfo_x86 *c = cpu_data + cpu;
                int siblings = 0;
                int i;
                if (!cpu_isset(cpu, cpu_callout_map))
@@ -1062,7 +1064,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                        for (i = 0; i < NR_CPUS; i++) {
                                if (!cpu_isset(i, cpu_callout_map))
                                        continue;
-                               if (phys_proc_id[cpu] == phys_proc_id[i]) {
+                               if (cpu_core_id[cpu] == cpu_core_id[i]) {
                                        siblings++;
                                        cpu_set(i, cpu_sibling_map[cpu]);
                                }
@@ -1072,12 +1074,23 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                        cpu_set(cpu, cpu_sibling_map[cpu]);
                }
 
-               if (siblings != smp_num_siblings)
+               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;
+               }
 
-       if (nmi_watchdog == NMI_LOCAL_APIC)
-               check_nmi_watchdog();
+               if (c->x86_num_cores > 1) {
+                       for (i = 0; i < NR_CPUS; i++) {
+                               if (!cpu_isset(i, cpu_callout_map))
+                                       continue;
+                               if (phys_proc_id[cpu] == phys_proc_id[i]) {
+                                       cpu_set(i, cpu_core_map[cpu]);
+                               }
+                       }
+               } else {
+                       cpu_core_map[cpu] = cpu_sibling_map[cpu];
+               }
+       }
 
        smpboot_setup_io_apic();