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

[Xen-devel] [PATCH v7 01/14] x86: add socket_to_cpumask



Maintain socket_to_cpumask which contains all the HT and core siblings
in the same socket.

Signed-off-by: Chao Peng <chao.p.peng@xxxxxxxxxxxxxxx>
---
Changes in v7:
* Introduce total_cpus to calculate nr_sockets.
* Minor code sequence improvement in set_cpu_sibling_map.
* Improve comments for nr_sockets.
---
 xen/arch/x86/mpparse.c    |  5 +++++
 xen/arch/x86/smpboot.c    | 25 +++++++++++++++++++++++--
 xen/include/asm-x86/smp.h | 16 ++++++++++++++++
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index 003c56e..23e6706 100644
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -64,6 +64,9 @@ unsigned int __read_mostly boot_cpu_physical_apicid = 
BAD_APICID;
 static unsigned int __devinitdata num_processors;
 static unsigned int __initdata disabled_cpus;
 
+/* Total detected cpus (may exceed NR_CPUS) */
+unsigned int total_cpus;
+
 /* Bitmask of physically existing CPUs */
 physid_mask_t phys_cpu_present_map;
 
@@ -112,6 +115,8 @@ static int __devinit MP_processor_info_x(struct 
mpc_config_processor *m,
 {
        int ver, apicid, cpu = 0;
        
+       total_cpus++;
+
        if (!(m->mpc_cpuflag & CPU_ENABLED)) {
                if (!hotplug)
                        ++disabled_cpus;
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 116c8f8..c5c25e4 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -59,6 +59,9 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_mask);
 cpumask_t cpu_online_map __read_mostly;
 EXPORT_SYMBOL(cpu_online_map);
 
+unsigned int nr_sockets __read_mostly;
+cpumask_var_t *socket_to_cpumask __read_mostly;
+
 struct cpuinfo_x86 cpu_data[NR_CPUS];
 
 u32 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
@@ -239,11 +242,14 @@ static void link_thread_siblings(int cpu1, int cpu2)
 
 static void set_cpu_sibling_map(int cpu)
 {
-    int i;
+    int i, socket = cpu_to_socket(cpu);
     struct cpuinfo_x86 *c = cpu_data;
 
     cpumask_set_cpu(cpu, &cpu_sibling_setup_map);
 
+    if ( socket < nr_sockets )
+        cpumask_set_cpu(cpu, socket_to_cpumask[socket]);
+
     if ( c[cpu].x86_num_siblings > 1 )
     {
         for_each_cpu ( i, &cpu_sibling_setup_map )
@@ -301,6 +307,7 @@ static void set_cpu_sibling_map(int cpu)
             }
         }
     }
+
 }
 
 void start_secondary(void *unused)
@@ -704,6 +711,8 @@ static struct notifier_block cpu_smpboot_nfb = {
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
+    int socket;
+
     register_cpu_notifier(&cpu_smpboot_nfb);
 
     mtrr_aps_sync_begin();
@@ -717,6 +726,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 
     stack_base[0] = stack_start;
 
+    nr_sockets = DIV_ROUND_UP(total_cpus, boot_cpu_data.x86_max_cores *
+                                          boot_cpu_data.x86_num_siblings);
+    socket_to_cpumask = xzalloc_array(cpumask_var_t, nr_sockets);
+    if ( !socket_to_cpumask )
+        panic("No memory for socket CPU siblings map");
+    for ( socket = 0; socket < nr_sockets; socket++ )
+        if ( !zalloc_cpumask_var(socket_to_cpumask + socket) )
+            panic("No memory for socket CPU siblings cpumask");
+
     if ( !zalloc_cpumask_var(&per_cpu(cpu_sibling_mask, 0)) ||
          !zalloc_cpumask_var(&per_cpu(cpu_core_mask, 0)) )
         panic("No memory for boot CPU sibling/core maps");
@@ -779,9 +797,12 @@ void __init smp_prepare_boot_cpu(void)
 static void
 remove_siblinginfo(int cpu)
 {
-    int sibling;
+    int sibling, socket = cpu_to_socket(cpu);
     struct cpuinfo_x86 *c = cpu_data;
 
+    if ( socket < nr_sockets )
+        cpumask_clear_cpu(cpu, socket_to_cpumask[socket]);
+
     for_each_cpu ( sibling, per_cpu(cpu_core_mask, cpu) )
     {
         cpumask_clear_cpu(cpu, per_cpu(cpu_core_mask, sibling));
diff --git a/xen/include/asm-x86/smp.h b/xen/include/asm-x86/smp.h
index 67518cf..30d8811 100644
--- a/xen/include/asm-x86/smp.h
+++ b/xen/include/asm-x86/smp.h
@@ -58,6 +58,22 @@ int hard_smp_processor_id(void);
 
 void __stop_this_cpu(void);
 
+/* Total number of cpus in this system (may exceed NR_CPUS) */
+extern unsigned int total_cpus;
+
+/*
+ * This value is calculated by total_cpus/cpus_per_socket with the assumption
+ * that APIC IDs from MP table are continuous. It's possible that this value
+ * is less than the real socket number in the system if the APIC IDs from MP
+ * table are too sparse. Also the value is considered not to change from the
+ * initial startup. Violation of any of these assumptions may result in errors
+ * and requires retrofitting all the relevant places.
+ */
+extern unsigned int nr_sockets;
+
+/* Representing HT and core siblings in each socket */
+extern cpumask_var_t *socket_to_cpumask;
+
 #endif /* !__ASSEMBLY__ */
 
 #endif
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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