#endif
}
+void __init set_nr_sockets(void)
+{
+ /*
+ * Count the actual cpus in the socket 0 and use it to calculate nr_sockets
+ * so that the latter will be always >= the actual socket number in the
+ * system even when APIC IDs from MP table are too sparse.
+ */
+ 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:
*/
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 =
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 )
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));
nodeid_t node = cpu_to_node(cpu);
struct desc_struct *gdt;
unsigned long stub_page;
+ unsigned int socket = cpu_to_socket(cpu);
if ( node != NUMA_NO_NODE )
memflags = MEMF_node(node);
goto oom;
per_cpu(stubs.addr, cpu) = stub_page + STUB_BUF_CPU_OFFS(cpu);
+ 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;
stack_base[0] = stack_start;
+ set_nr_sockets();
+
+ socket_cpumask = xzalloc_array(cpumask_var_t, nr_sockets);
+ if ( !socket_cpumask || !zalloc_cpumask_var(socket_cpumask) )
+ panic("No memory for socket CPU siblings map");
+
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");
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));