|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v8 01/13] x86: add socket_cpumask
Maintain socket_cpumask which contains all the HT and core siblings
in the same socket.
Signed-off-by: Chao Peng <chao.p.peng@xxxxxxxxxxxxxxx>
---
Changes in v8:
* Remove total_cpus and retrofit the algorithm for calculating nr_sockets.
* Change per-socket cpumask allocation as on demand.
* socket_to_cpumask => socket_cpumask.
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 | 12 ++++++++++++
xen/arch/x86/setup.c | 2 ++
xen/arch/x86/smpboot.c | 27 ++++++++++++++++++++++++++-
xen/include/asm-x86/setup.h | 1 +
xen/include/asm-x86/smp.h | 9 +++++++++
5 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index 003c56e..fb34492 100644
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -87,6 +87,18 @@ void __init set_nr_cpu_ids(unsigned int max_cpus)
#endif
}
+void __init set_nr_sockets(void)
+{
+ unsigned int cpus = bitmap_weight(phys_cpu_present_map.mask,
+ boot_cpu_data.x86_max_cores *
+ boot_cpu_data.x86_num_siblings);
+
+ if ( cpus == 0 )
+ cpus = 1;
+
+ nr_sockets = DIV_ROUND_UP(num_processors + disabled_cpus, cpus);
+}
+
/*
* Intel MP BIOS table parsing routines:
*/
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 2b9787a..a864ca8 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1280,6 +1280,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
identify_cpu(&boot_cpu_data);
+ set_nr_sockets();
+
if ( cpu_has_fxsr )
set_in_cr4(X86_CR4_OSFXSR);
if ( cpu_has_xmm )
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 116c8f8..38431eb 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 __read_mostly nr_sockets;
+cpumask_var_t *__read_mostly socket_cpumask;
+
struct cpuinfo_x86 cpu_data[NR_CPUS];
u32 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
@@ -244,6 +247,8 @@ static void set_cpu_sibling_map(int cpu)
cpumask_set_cpu(cpu, &cpu_sibling_setup_map);
+ cpumask_set_cpu(cpu, socket_cpumask[cpu_to_socket(cpu)]);
+
if ( c[cpu].x86_num_siblings > 1 )
{
for_each_cpu ( i, &cpu_sibling_setup_map )
@@ -611,7 +616,13 @@ void cpu_exit_clear(unsigned int cpu)
static void cpu_smpboot_free(unsigned int cpu)
{
- unsigned int order;
+ unsigned int order, socket = cpu_to_socket(cpu);
+
+ if ( cpumask_empty(socket_cpumask[socket]) )
+ {
+ free_cpumask_var(socket_cpumask[socket]);
+ socket_cpumask[socket] = NULL;
+ }
free_cpumask_var(per_cpu(cpu_sibling_mask, cpu));
free_cpumask_var(per_cpu(cpu_core_mask, cpu));
@@ -638,6 +649,8 @@ static int cpu_smpboot_alloc(unsigned int cpu)
unsigned int order, memflags = 0;
nodeid_t node = cpu_to_node(cpu);
struct desc_struct *gdt;
+ unsigned int socket = cpu_to_socket(cpu);
+
if ( node != NUMA_NO_NODE )
memflags = MEMF_node(node);
@@ -667,6 +680,10 @@ static int cpu_smpboot_alloc(unsigned int cpu)
goto oom;
memcpy(idt_tables[cpu], idt_table, IDT_ENTRIES * sizeof(idt_entry_t));
+ if ( !socket_cpumask[socket] &&
+ !zalloc_cpumask_var(socket_cpumask + socket) )
+ goto oom;
+
if ( zalloc_cpumask_var(&per_cpu(cpu_sibling_mask, cpu)) &&
zalloc_cpumask_var(&per_cpu(cpu_core_mask, cpu)) )
return 0;
@@ -717,6 +734,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
stack_base[0] = stack_start;
+ socket_cpumask = xzalloc_array(cpumask_var_t, nr_sockets);
+ if ( !socket_cpumask )
+ panic("No memory for socket CPU siblings map");
+ if ( !zalloc_cpumask_var(socket_cpumask) )
+ 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");
@@ -782,6 +805,8 @@ remove_siblinginfo(int cpu)
int sibling;
struct cpuinfo_x86 *c = cpu_data;
+ cpumask_clear_cpu(cpu, socket_cpumask[cpu_to_socket(cpu)]);
+
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/setup.h b/xen/include/asm-x86/setup.h
index 08bc23a..597cedf 100644
--- a/xen/include/asm-x86/setup.h
+++ b/xen/include/asm-x86/setup.h
@@ -17,6 +17,7 @@ int centaur_init_cpu(void);
int transmeta_init_cpu(void);
void set_nr_cpu_ids(unsigned int max_cpus);
+void set_nr_sockets(void);
void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn);
void arch_init_memory(void);
diff --git a/xen/include/asm-x86/smp.h b/xen/include/asm-x86/smp.h
index 67518cf..2087a77 100644
--- a/xen/include/asm-x86/smp.h
+++ b/xen/include/asm-x86/smp.h
@@ -58,6 +58,15 @@ int hard_smp_processor_id(void);
void __stop_this_cpu(void);
+/*
+ * The value may be greater than the actual socket number in the system and
+ * is considered not to change from the initial startup.
+ */
+extern unsigned int nr_sockets;
+
+/* Representing HT and core siblings in each socket */
+extern cpumask_var_t *socket_cpumask;
+
#endif /* !__ASSEMBLY__ */
#endif
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |