From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chao Peng Subject: [PATCH v8 01/13] x86: add socket_cpumask Date: Thu, 21 May 2015 16:41:32 +0800 Message-ID: <1432197704-20816-2-git-send-email-chao.p.peng@linux.intel.com> References: <1432197704-20816-1-git-send-email-chao.p.peng@linux.intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1432197704-20816-1-git-send-email-chao.p.peng@linux.intel.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: keir@xen.org, Ian.Campbell@citrix.com, stefano.stabellini@eu.citrix.com, andrew.cooper3@citrix.com, dario.faggioli@citrix.com, Ian.Jackson@eu.citrix.com, will.auld@intel.com, JBeulich@suse.com, wei.liu2@citrix.com, dgdegra@tycho.nsa.gov List-Id: xen-devel@lists.xenproject.org Maintain socket_cpumask which contains all the HT and core siblings in the same socket. Signed-off-by: Chao Peng --- 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