[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Mark CPU present when it is detected



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1257858285 0
# Node ID 918f692f60688fee14f94ded3ea02c249003c69a
# Parent  d492ebacff21f7f8458bbbbbaa22336a1865487b
Mark CPU present when it is detected

Currently a CPU is marked as present only after it has been kicked off
successfully, i.e. before the CPU is brought up, it is not
present. This patch try to mark CPU as present when it is detected
(either through MPS table or ACPI). If it can't be brought up
successfully, it will be marked as non-present again.  This change is
mainly for CPU hot-plug. As discussed, we'd take two step for physical
CPU hot-add. A CPU is firstly marked as present, and later will bring
as online.

Also, In smp_boot_cpus(), xen need only scan all present CPU, and no
need to loop from 0... NR_CPUS. With this change, the bios_cpu_apicid
is not needed anymore.

Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx>
---
 xen/arch/x86/mpparse.c                       |   38 +++++++++++++++++----------
 xen/arch/x86/smpboot.c                       |   28 ++++++++++++++-----
 xen/include/asm-x86/mach-generic/mach_apic.h |    7 ----
 xen/include/asm-x86/mpspec.h                 |    3 +-
 xen/include/xen/smp.h                        |    2 +
 5 files changed, 50 insertions(+), 28 deletions(-)

diff -r d492ebacff21 -r 918f692f6068 xen/arch/x86/mpparse.c
--- a/xen/arch/x86/mpparse.c    Tue Nov 10 13:03:42 2009 +0000
+++ b/xen/arch/x86/mpparse.c    Tue Nov 10 13:04:45 2009 +0000
@@ -71,8 +71,6 @@ static unsigned int __devinitdata num_pr
 /* Bitmask of physically existing CPUs */
 physid_mask_t phys_cpu_present_map;
 
-u32 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
-
 /*
  * Intel MP BIOS table parsing routines:
  */
@@ -101,13 +99,14 @@ static int mpc_record;
 static int mpc_record; 
 static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] 
__initdata;
 
-static void __devinit MP_processor_info (struct mpc_config_processor *m)
-{
-       int ver, apicid;
+/* Return xen's logical cpu_id of the new added cpu or <0 if error */
+static int __devinit MP_processor_info (struct mpc_config_processor *m)
+{
+       int ver, apicid, cpu = 0;
        physid_mask_t phys_cpu;
        
        if (!(m->mpc_cpuflag & CPU_ENABLED))
-               return;
+               return -EINVAL;
 
        apicid = mpc_apic_id(m, translation_table[mpc_record]);
 
@@ -183,14 +182,26 @@ static void __devinit MP_processor_info 
        if (num_processors >= NR_CPUS) {
                printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
                        "  Processor ignored.\n", NR_CPUS);
-               return;
+               return -ENOSPC;
        }
 
        if (num_processors >= maxcpus) {
                printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
                        " Processor ignored.\n", maxcpus);
-               return;
-       }
+               return -ENOSPC;
+       }
+
+    /* Boot cpu has been marked present in smp_prepare_boot_cpu */
+    if (!(m->mpc_cpuflag & CPU_BOOTPROCESSOR)) {
+        cpu = alloc_cpu_id();
+        if (cpu < 0) {
+            printk(KERN_WARNING "WARNING: Can't alloc cpu_id."
+              " Processor with apicid %i ignored\n", apicid);
+            return cpu;
+        }
+        x86_cpu_to_apicid[cpu] = apicid;
+        cpu_set(cpu, cpu_present_map);
+    }
 
        cpu_set(num_processors, cpu_possible_map);
        num_processors++;
@@ -202,7 +213,8 @@ static void __devinit MP_processor_info 
                 */
                def_to_bigsmp = 1;
        }
-       bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
+
+    return cpu;
 }
 
 static void __init MP_bus_info (struct mpc_config_bus *m)
@@ -826,7 +838,7 @@ void __init mp_register_lapic_address (
 }
 
 
-void __devinit mp_register_lapic (
+int __devinit mp_register_lapic (
        u8                      id, 
        u8                      enabled)
 {
@@ -836,7 +848,7 @@ void __devinit mp_register_lapic (
        if (MAX_APICS - id <= 0) {
                printk(KERN_WARNING "Processor #%d invalid (max %d)\n",
                        id, MAX_APICS);
-               return;
+               return -EINVAL;
        }
 
        if (id == boot_cpu_physical_apicid)
@@ -853,7 +865,7 @@ void __devinit mp_register_lapic (
        processor.mpc_reserved[0] = 0;
        processor.mpc_reserved[1] = 0;
 
-       MP_processor_info(&processor);
+    return MP_processor_info(&processor);
 }
 
 #ifdef CONFIG_X86_IO_APIC
diff -r d492ebacff21 -r 918f692f6068 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Tue Nov 10 13:03:42 2009 +0000
+++ b/xen/arch/x86/smpboot.c    Tue Nov 10 13:04:45 2009 +0000
@@ -800,7 +800,10 @@ wakeup_secondary_cpu(int phys_apicid, un
 #endif /* WAKE_SECONDARY_VIA_INIT */
 
 extern cpumask_t cpu_initialized;
-static inline int alloc_cpu_id(void)
+/*
+ * Caller should hold cpu_add_remove_lock if not called when booting
+ */
+int alloc_cpu_id(void)
 {
        cpumask_t       tmp_map;
        int cpu;
@@ -959,9 +962,13 @@ static int __devinit do_boot_cpu(int api
                cpu_clear(cpu, cpu_callout_map); /* was set here 
(do_boot_cpu()) */
                cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
                cpucount--;
+
+        /* Mark the CPU as non-present */
+        spin_lock(&cpu_add_remove_lock);
+               x86_cpu_to_apicid[cpu] = BAD_APICID;
+               cpu_clear(cpu, cpu_present_map);
+        spin_unlock(&cpu_add_remove_lock);
        } else {
-               x86_cpu_to_apicid[cpu] = apicid;
-               cpu_set(cpu, cpu_present_map);
        }
 
        /* mark "stuck" area as not stuck */
@@ -1028,7 +1035,7 @@ EXPORT_SYMBOL(xquad_portio);
 
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
-       int apicid, cpu, bit, kicked;
+       int apicid, cpu, kicked;
 #ifdef BOGOMIPS
        unsigned long bogosum = 0;
 #endif
@@ -1112,8 +1119,11 @@ static void __init smp_boot_cpus(unsigne
        Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map));
 
        kicked = 1;
-       for (bit = 0; kicked < NR_CPUS && bit < NR_CPUS; bit++) {
-               apicid = cpu_present_to_apicid(bit);
+
+    for_each_present_cpu ( cpu )
+    {
+               apicid = x86_cpu_to_apicid[cpu];
+
                /*
                 * Don't even attempt to start the boot CPU!
                 */
@@ -1121,11 +1131,15 @@ static void __init smp_boot_cpus(unsigne
                        continue;
 
                if (!check_apicid_present(apicid))
+        {
+            dprintk(XENLOG_WARNING, "Present CPU has valid apicid\n");
                        continue;
+        }
+
                if (max_cpus <= cpucount+1)
                        continue;
 
-               if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
+               if ( do_boot_cpu(apicid, cpu))
                        printk("CPU #%d not responding - cannot use it.\n",
                                                                apicid);
                else
diff -r d492ebacff21 -r 918f692f6068 
xen/include/asm-x86/mach-generic/mach_apic.h
--- a/xen/include/asm-x86/mach-generic/mach_apic.h      Tue Nov 10 13:03:42 
2009 +0000
+++ b/xen/include/asm-x86/mach-generic/mach_apic.h      Tue Nov 10 13:04:45 
2009 +0000
@@ -25,13 +25,6 @@ static inline void enable_apic_mode(void
 #define apicid_to_node(apicid) ((int)apicid_to_node[(u32)apicid])
 
 extern u32 bios_cpu_apicid[];
-static inline int cpu_present_to_apicid(int mps_cpu)
-{
-       if (mps_cpu < NR_CPUS)
-               return (int)bios_cpu_apicid[mps_cpu];
-       else
-               return BAD_APICID;
-}
 
 static inline int mpc_apic_id(struct mpc_config_processor *m, 
                        struct mpc_config_translation *translation_record)
diff -r d492ebacff21 -r 918f692f6068 xen/include/asm-x86/mpspec.h
--- a/xen/include/asm-x86/mpspec.h      Tue Nov 10 13:03:42 2009 +0000
+++ b/xen/include/asm-x86/mpspec.h      Tue Nov 10 13:04:45 2009 +0000
@@ -25,7 +25,8 @@ extern int using_apic_timer;
 extern int using_apic_timer;
 
 #ifdef CONFIG_ACPI
-extern void mp_register_lapic (u8 id, u8 enabled);
+extern int mp_register_lapic (u8 id, u8 enabled);
+extern void mp_unregister_lapic(uint32_t apic_id, uint32_t cpu);
 extern void mp_register_lapic_address (u64 address);
 extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
 extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 
gsi);
diff -r d492ebacff21 -r 918f692f6068 xen/include/xen/smp.h
--- a/xen/include/xen/smp.h     Tue Nov 10 13:03:42 2009 +0000
+++ b/xen/include/xen/smp.h     Tue Nov 10 13:04:45 2009 +0000
@@ -68,4 +68,6 @@ static inline int on_each_cpu(
 #define lock_cpu_hotplug() ((void)0)
 #define unlock_cpu_hotplug() ((void)0)
 
+int alloc_cpu_id(void);
+
 #endif /* __XEN_SMP_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.