Merge branch 'x86/numa' into x86/mm
Merge reason: consolidate it into the more generic x86/mm tree to prevent conflicts. Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
@@ -589,14 +589,8 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
|
||||
nid = acpi_get_node(handle);
|
||||
if (nid == -1 || !node_online(nid))
|
||||
return;
|
||||
#ifdef CONFIG_X86_64
|
||||
apicid_to_node[physid] = nid;
|
||||
set_apicid_to_node(physid, nid);
|
||||
numa_set_node(cpu, nid);
|
||||
#else /* CONFIG_X86_32 */
|
||||
apicid_2_node[physid] = nid;
|
||||
cpu_to_node_map[cpu] = nid;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,15 @@ EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
|
||||
EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
|
||||
/*
|
||||
* On x86_32, the mapping between cpu and logical apicid may vary
|
||||
* depending on apic in use. The following early percpu variable is
|
||||
* used for the mapping. This is where the behaviors of x86_64 and 32
|
||||
* actually diverge. Let's keep it ugly for now.
|
||||
*/
|
||||
DEFINE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid, BAD_APICID);
|
||||
|
||||
/*
|
||||
* Knob to control our willingness to enable the local APIC.
|
||||
*
|
||||
@@ -1237,6 +1246,19 @@ void __cpuinit setup_local_APIC(void)
|
||||
*/
|
||||
apic->init_apic_ldr();
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/*
|
||||
* APIC LDR is initialized. If logical_apicid mapping was
|
||||
* initialized during get_smp_config(), make sure it matches the
|
||||
* actual value.
|
||||
*/
|
||||
i = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
|
||||
WARN_ON(i != BAD_APICID && i != logical_smp_processor_id());
|
||||
/* always use the value from LDR */
|
||||
early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
|
||||
logical_smp_processor_id();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set Task Priority to 'accept all'. We never change this
|
||||
* later on.
|
||||
@@ -1972,7 +1994,10 @@ void __cpuinit generic_processor_info(int apicid, int version)
|
||||
early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
|
||||
early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
|
||||
apic->x86_32_early_logical_apicid(cpu);
|
||||
#endif
|
||||
set_cpu_possible(cpu, true);
|
||||
set_cpu_present(cpu, true);
|
||||
}
|
||||
@@ -1993,10 +2018,14 @@ void default_init_apic_ldr(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
int default_apicid_to_node(int logical_apicid)
|
||||
int default_x86_32_numa_cpu_node(int cpu)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
return apicid_2_node[hard_smp_processor_id()];
|
||||
#ifdef CONFIG_NUMA
|
||||
int apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
|
||||
|
||||
if (apicid != BAD_APICID)
|
||||
return __apicid_to_node[apicid];
|
||||
return NUMA_NO_NODE;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -185,8 +185,6 @@ struct apic apic_flat = {
|
||||
.ioapic_phys_id_map = NULL,
|
||||
.setup_apic_routing = NULL,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = NULL,
|
||||
.cpu_to_logical_apicid = NULL,
|
||||
.cpu_present_to_apicid = default_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = NULL,
|
||||
.setup_portio_remap = NULL,
|
||||
@@ -337,8 +335,6 @@ struct apic apic_physflat = {
|
||||
.ioapic_phys_id_map = NULL,
|
||||
.setup_apic_routing = NULL,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = NULL,
|
||||
.cpu_to_logical_apicid = NULL,
|
||||
.cpu_present_to_apicid = default_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = NULL,
|
||||
.setup_portio_remap = NULL,
|
||||
|
||||
@@ -54,11 +54,6 @@ static u64 noop_apic_icr_read(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int noop_cpu_to_logical_apicid(int cpu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int noop_phys_pkg_id(int cpuid_apic, int index_msb)
|
||||
{
|
||||
return 0;
|
||||
@@ -113,12 +108,6 @@ static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask)
|
||||
cpumask_set_cpu(cpu, retmask);
|
||||
}
|
||||
|
||||
int noop_apicid_to_node(int logical_apicid)
|
||||
{
|
||||
/* we're always on node 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 noop_apic_read(u32 reg)
|
||||
{
|
||||
WARN_ON_ONCE((cpu_has_apic && !disable_apic));
|
||||
@@ -130,6 +119,14 @@ static void noop_apic_write(u32 reg, u32 v)
|
||||
WARN_ON_ONCE(cpu_has_apic && !disable_apic);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
static int noop_x86_32_numa_cpu_node(int cpu)
|
||||
{
|
||||
/* we're always on node 0 */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct apic apic_noop = {
|
||||
.name = "noop",
|
||||
.probe = noop_probe,
|
||||
@@ -153,9 +150,7 @@ struct apic apic_noop = {
|
||||
.ioapic_phys_id_map = default_ioapic_phys_id_map,
|
||||
.setup_apic_routing = NULL,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = noop_apicid_to_node,
|
||||
|
||||
.cpu_to_logical_apicid = noop_cpu_to_logical_apicid,
|
||||
.cpu_present_to_apicid = default_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = physid_set_mask_of_physid,
|
||||
|
||||
@@ -197,4 +192,9 @@ struct apic apic_noop = {
|
||||
.icr_write = noop_apic_icr_write,
|
||||
.wait_icr_idle = noop_apic_wait_icr_idle,
|
||||
.safe_wait_icr_idle = noop_safe_apic_wait_icr_idle,
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
.x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
|
||||
.x86_32_numa_cpu_node = noop_x86_32_numa_cpu_node,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -45,6 +45,12 @@ static unsigned long bigsmp_check_apicid_present(int bit)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bigsmp_early_logical_apicid(int cpu)
|
||||
{
|
||||
/* on bigsmp, logical apicid is the same as physical */
|
||||
return early_per_cpu(x86_cpu_to_apicid, cpu);
|
||||
}
|
||||
|
||||
static inline unsigned long calculate_ldr(int cpu)
|
||||
{
|
||||
unsigned long val, id;
|
||||
@@ -80,11 +86,6 @@ static void bigsmp_setup_apic_routing(void)
|
||||
nr_ioapics);
|
||||
}
|
||||
|
||||
static int bigsmp_apicid_to_node(int logical_apicid)
|
||||
{
|
||||
return apicid_2_node[hard_smp_processor_id()];
|
||||
}
|
||||
|
||||
static int bigsmp_cpu_present_to_apicid(int mps_cpu)
|
||||
{
|
||||
if (mps_cpu < nr_cpu_ids)
|
||||
@@ -93,14 +94,6 @@ static int bigsmp_cpu_present_to_apicid(int mps_cpu)
|
||||
return BAD_APICID;
|
||||
}
|
||||
|
||||
/* Mapping from cpu number to logical apicid */
|
||||
static inline int bigsmp_cpu_to_logical_apicid(int cpu)
|
||||
{
|
||||
if (cpu >= nr_cpu_ids)
|
||||
return BAD_APICID;
|
||||
return cpu_physical_id(cpu);
|
||||
}
|
||||
|
||||
static void bigsmp_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
|
||||
{
|
||||
/* For clustered we don't have a good way to do this yet - hack */
|
||||
@@ -115,7 +108,11 @@ static int bigsmp_check_phys_apicid_present(int phys_apicid)
|
||||
/* As we are using single CPU as destination, pick only one CPU here */
|
||||
static unsigned int bigsmp_cpu_mask_to_apicid(const struct cpumask *cpumask)
|
||||
{
|
||||
return bigsmp_cpu_to_logical_apicid(cpumask_first(cpumask));
|
||||
int cpu = cpumask_first(cpumask);
|
||||
|
||||
if (cpu < nr_cpu_ids)
|
||||
return cpu_physical_id(cpu);
|
||||
return BAD_APICID;
|
||||
}
|
||||
|
||||
static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||
@@ -129,9 +126,9 @@ static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||
*/
|
||||
for_each_cpu_and(cpu, cpumask, andmask) {
|
||||
if (cpumask_test_cpu(cpu, cpu_online_mask))
|
||||
break;
|
||||
return cpu_physical_id(cpu);
|
||||
}
|
||||
return bigsmp_cpu_to_logical_apicid(cpu);
|
||||
return BAD_APICID;
|
||||
}
|
||||
|
||||
static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
|
||||
@@ -219,8 +216,6 @@ struct apic apic_bigsmp = {
|
||||
.ioapic_phys_id_map = bigsmp_ioapic_phys_id_map,
|
||||
.setup_apic_routing = bigsmp_setup_apic_routing,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = bigsmp_apicid_to_node,
|
||||
.cpu_to_logical_apicid = bigsmp_cpu_to_logical_apicid,
|
||||
.cpu_present_to_apicid = bigsmp_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = physid_set_mask_of_physid,
|
||||
.setup_portio_remap = NULL,
|
||||
@@ -256,4 +251,7 @@ struct apic apic_bigsmp = {
|
||||
.icr_write = native_apic_icr_write,
|
||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||
|
||||
.x86_32_early_logical_apicid = bigsmp_early_logical_apicid,
|
||||
.x86_32_numa_cpu_node = default_x86_32_numa_cpu_node,
|
||||
};
|
||||
|
||||
@@ -460,6 +460,12 @@ static unsigned long es7000_check_apicid_present(int bit)
|
||||
return physid_isset(bit, phys_cpu_present_map);
|
||||
}
|
||||
|
||||
static int es7000_early_logical_apicid(int cpu)
|
||||
{
|
||||
/* on es7000, logical apicid is the same as physical */
|
||||
return early_per_cpu(x86_bios_cpu_apicid, cpu);
|
||||
}
|
||||
|
||||
static unsigned long calculate_ldr(int cpu)
|
||||
{
|
||||
unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu);
|
||||
@@ -504,12 +510,11 @@ static void es7000_setup_apic_routing(void)
|
||||
nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
|
||||
}
|
||||
|
||||
static int es7000_apicid_to_node(int logical_apicid)
|
||||
static int es7000_numa_cpu_node(int cpu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int es7000_cpu_present_to_apicid(int mps_cpu)
|
||||
{
|
||||
if (!mps_cpu)
|
||||
@@ -528,18 +533,6 @@ static void es7000_apicid_to_cpu_present(int phys_apicid, physid_mask_t *retmap)
|
||||
++cpu_id;
|
||||
}
|
||||
|
||||
/* Mapping from cpu number to logical apicid */
|
||||
static int es7000_cpu_to_logical_apicid(int cpu)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
if (cpu >= nr_cpu_ids)
|
||||
return BAD_APICID;
|
||||
return cpu_2_logical_apicid[cpu];
|
||||
#else
|
||||
return logical_smp_processor_id();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void es7000_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
|
||||
{
|
||||
/* For clustered we don't have a good way to do this yet - hack */
|
||||
@@ -561,7 +554,7 @@ static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)
|
||||
* The cpus in the mask must all be on the apic cluster.
|
||||
*/
|
||||
for_each_cpu(cpu, cpumask) {
|
||||
int new_apicid = es7000_cpu_to_logical_apicid(cpu);
|
||||
int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
|
||||
|
||||
if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
|
||||
WARN(1, "Not a valid mask!");
|
||||
@@ -578,7 +571,7 @@ static unsigned int
|
||||
es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
|
||||
const struct cpumask *andmask)
|
||||
{
|
||||
int apicid = es7000_cpu_to_logical_apicid(0);
|
||||
int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);
|
||||
cpumask_var_t cpumask;
|
||||
|
||||
if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
|
||||
@@ -655,8 +648,6 @@ struct apic __refdata apic_es7000_cluster = {
|
||||
.ioapic_phys_id_map = es7000_ioapic_phys_id_map,
|
||||
.setup_apic_routing = es7000_setup_apic_routing,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = es7000_apicid_to_node,
|
||||
.cpu_to_logical_apicid = es7000_cpu_to_logical_apicid,
|
||||
.cpu_present_to_apicid = es7000_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = es7000_apicid_to_cpu_present,
|
||||
.setup_portio_remap = NULL,
|
||||
@@ -695,6 +686,9 @@ struct apic __refdata apic_es7000_cluster = {
|
||||
.icr_write = native_apic_icr_write,
|
||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||
|
||||
.x86_32_early_logical_apicid = es7000_early_logical_apicid,
|
||||
.x86_32_numa_cpu_node = es7000_numa_cpu_node,
|
||||
};
|
||||
|
||||
struct apic __refdata apic_es7000 = {
|
||||
@@ -720,8 +714,6 @@ struct apic __refdata apic_es7000 = {
|
||||
.ioapic_phys_id_map = es7000_ioapic_phys_id_map,
|
||||
.setup_apic_routing = es7000_setup_apic_routing,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = es7000_apicid_to_node,
|
||||
.cpu_to_logical_apicid = es7000_cpu_to_logical_apicid,
|
||||
.cpu_present_to_apicid = es7000_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = es7000_apicid_to_cpu_present,
|
||||
.setup_portio_remap = NULL,
|
||||
@@ -758,4 +750,7 @@ struct apic __refdata apic_es7000 = {
|
||||
.icr_write = native_apic_icr_write,
|
||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||
|
||||
.x86_32_early_logical_apicid = es7000_early_logical_apicid,
|
||||
.x86_32_numa_cpu_node = es7000_numa_cpu_node,
|
||||
};
|
||||
|
||||
@@ -56,6 +56,8 @@ void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask,
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
|
||||
void default_send_IPI_mask_sequence_logical(const struct cpumask *mask,
|
||||
int vector)
|
||||
{
|
||||
@@ -71,8 +73,8 @@ void default_send_IPI_mask_sequence_logical(const struct cpumask *mask,
|
||||
local_irq_save(flags);
|
||||
for_each_cpu(query_cpu, mask)
|
||||
__default_send_IPI_dest_field(
|
||||
apic->cpu_to_logical_apicid(query_cpu), vector,
|
||||
apic->dest_logical);
|
||||
early_per_cpu(x86_cpu_to_logical_apicid, query_cpu),
|
||||
vector, apic->dest_logical);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
@@ -90,14 +92,12 @@ void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask,
|
||||
if (query_cpu == this_cpu)
|
||||
continue;
|
||||
__default_send_IPI_dest_field(
|
||||
apic->cpu_to_logical_apicid(query_cpu), vector,
|
||||
apic->dest_logical);
|
||||
early_per_cpu(x86_cpu_to_logical_apicid, query_cpu),
|
||||
vector, apic->dest_logical);
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
|
||||
/*
|
||||
* This is only used on smaller machines.
|
||||
*/
|
||||
|
||||
@@ -373,13 +373,6 @@ static inline void numaq_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask
|
||||
return physids_promote(0xFUL, retmap);
|
||||
}
|
||||
|
||||
static inline int numaq_cpu_to_logical_apicid(int cpu)
|
||||
{
|
||||
if (cpu >= nr_cpu_ids)
|
||||
return BAD_APICID;
|
||||
return cpu_2_logical_apicid[cpu];
|
||||
}
|
||||
|
||||
/*
|
||||
* Supporting over 60 cpus on NUMA-Q requires a locality-dependent
|
||||
* cpu to APIC ID relation to properly interact with the intelligent
|
||||
@@ -398,6 +391,15 @@ static inline int numaq_apicid_to_node(int logical_apicid)
|
||||
return logical_apicid >> 4;
|
||||
}
|
||||
|
||||
static int numaq_numa_cpu_node(int cpu)
|
||||
{
|
||||
int logical_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
|
||||
|
||||
if (logical_apicid != BAD_APICID)
|
||||
return numaq_apicid_to_node(logical_apicid);
|
||||
return NUMA_NO_NODE;
|
||||
}
|
||||
|
||||
static void numaq_apicid_to_cpu_present(int logical_apicid, physid_mask_t *retmap)
|
||||
{
|
||||
int node = numaq_apicid_to_node(logical_apicid);
|
||||
@@ -508,8 +510,6 @@ struct apic __refdata apic_numaq = {
|
||||
.ioapic_phys_id_map = numaq_ioapic_phys_id_map,
|
||||
.setup_apic_routing = numaq_setup_apic_routing,
|
||||
.multi_timer_check = numaq_multi_timer_check,
|
||||
.apicid_to_node = numaq_apicid_to_node,
|
||||
.cpu_to_logical_apicid = numaq_cpu_to_logical_apicid,
|
||||
.cpu_present_to_apicid = numaq_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = numaq_apicid_to_cpu_present,
|
||||
.setup_portio_remap = numaq_setup_portio_remap,
|
||||
@@ -547,4 +547,7 @@ struct apic __refdata apic_numaq = {
|
||||
.icr_write = native_apic_icr_write,
|
||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||
|
||||
.x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
|
||||
.x86_32_numa_cpu_node = numaq_numa_cpu_node,
|
||||
};
|
||||
|
||||
@@ -77,6 +77,11 @@ void __init default_setup_apic_routing(void)
|
||||
apic->setup_apic_routing();
|
||||
}
|
||||
|
||||
static int default_x86_32_early_logical_apicid(int cpu)
|
||||
{
|
||||
return 1 << cpu;
|
||||
}
|
||||
|
||||
static void setup_apic_flat_routing(void)
|
||||
{
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
@@ -130,8 +135,6 @@ struct apic apic_default = {
|
||||
.ioapic_phys_id_map = default_ioapic_phys_id_map,
|
||||
.setup_apic_routing = setup_apic_flat_routing,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = default_apicid_to_node,
|
||||
.cpu_to_logical_apicid = default_cpu_to_logical_apicid,
|
||||
.cpu_present_to_apicid = default_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = physid_set_mask_of_physid,
|
||||
.setup_portio_remap = NULL,
|
||||
@@ -167,6 +170,9 @@ struct apic apic_default = {
|
||||
.icr_write = native_apic_icr_write,
|
||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||
|
||||
.x86_32_early_logical_apicid = default_x86_32_early_logical_apicid,
|
||||
.x86_32_numa_cpu_node = default_x86_32_numa_cpu_node,
|
||||
};
|
||||
|
||||
extern struct apic apic_numaq;
|
||||
|
||||
@@ -194,11 +194,10 @@ static unsigned long summit_check_apicid_present(int bit)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void summit_init_apic_ldr(void)
|
||||
static int summit_early_logical_apicid(int cpu)
|
||||
{
|
||||
unsigned long val, id;
|
||||
int count = 0;
|
||||
u8 my_id = (u8)hard_smp_processor_id();
|
||||
u8 my_id = early_per_cpu(x86_cpu_to_apicid, cpu);
|
||||
u8 my_cluster = APIC_CLUSTER(my_id);
|
||||
#ifdef CONFIG_SMP
|
||||
u8 lid;
|
||||
@@ -206,7 +205,7 @@ static void summit_init_apic_ldr(void)
|
||||
|
||||
/* Create logical APIC IDs by counting CPUs already in cluster. */
|
||||
for (count = 0, i = nr_cpu_ids; --i >= 0; ) {
|
||||
lid = cpu_2_logical_apicid[i];
|
||||
lid = early_per_cpu(x86_cpu_to_logical_apicid, i);
|
||||
if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster)
|
||||
++count;
|
||||
}
|
||||
@@ -214,7 +213,15 @@ static void summit_init_apic_ldr(void)
|
||||
/* We only have a 4 wide bitmap in cluster mode. If a deranged
|
||||
* BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
|
||||
BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
|
||||
id = my_cluster | (1UL << count);
|
||||
return my_cluster | (1UL << count);
|
||||
}
|
||||
|
||||
static void summit_init_apic_ldr(void)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
unsigned long id = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
|
||||
unsigned long val;
|
||||
|
||||
apic_write(APIC_DFR, SUMMIT_APIC_DFR_VALUE);
|
||||
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
|
||||
val |= SET_APIC_LOGICAL_ID(id);
|
||||
@@ -232,27 +239,6 @@ static void summit_setup_apic_routing(void)
|
||||
nr_ioapics);
|
||||
}
|
||||
|
||||
static int summit_apicid_to_node(int logical_apicid)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
return apicid_2_node[hard_smp_processor_id()];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Mapping from cpu number to logical apicid */
|
||||
static inline int summit_cpu_to_logical_apicid(int cpu)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
if (cpu >= nr_cpu_ids)
|
||||
return BAD_APICID;
|
||||
return cpu_2_logical_apicid[cpu];
|
||||
#else
|
||||
return logical_smp_processor_id();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int summit_cpu_present_to_apicid(int mps_cpu)
|
||||
{
|
||||
if (mps_cpu < nr_cpu_ids)
|
||||
@@ -286,7 +272,7 @@ static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask)
|
||||
* The cpus in the mask must all be on the apic cluster.
|
||||
*/
|
||||
for_each_cpu(cpu, cpumask) {
|
||||
int new_apicid = summit_cpu_to_logical_apicid(cpu);
|
||||
int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
|
||||
|
||||
if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
|
||||
printk("%s: Not a valid mask!\n", __func__);
|
||||
@@ -301,7 +287,7 @@ static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask)
|
||||
static unsigned int summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
|
||||
const struct cpumask *andmask)
|
||||
{
|
||||
int apicid = summit_cpu_to_logical_apicid(0);
|
||||
int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);
|
||||
cpumask_var_t cpumask;
|
||||
|
||||
if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
|
||||
@@ -528,8 +514,6 @@ struct apic apic_summit = {
|
||||
.ioapic_phys_id_map = summit_ioapic_phys_id_map,
|
||||
.setup_apic_routing = summit_setup_apic_routing,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = summit_apicid_to_node,
|
||||
.cpu_to_logical_apicid = summit_cpu_to_logical_apicid,
|
||||
.cpu_present_to_apicid = summit_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = summit_apicid_to_cpu_present,
|
||||
.setup_portio_remap = NULL,
|
||||
@@ -565,4 +549,7 @@ struct apic apic_summit = {
|
||||
.icr_write = native_apic_icr_write,
|
||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||
|
||||
.x86_32_early_logical_apicid = summit_early_logical_apicid,
|
||||
.x86_32_numa_cpu_node = default_x86_32_numa_cpu_node,
|
||||
};
|
||||
|
||||
@@ -206,8 +206,6 @@ struct apic apic_x2apic_cluster = {
|
||||
.ioapic_phys_id_map = NULL,
|
||||
.setup_apic_routing = NULL,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = NULL,
|
||||
.cpu_to_logical_apicid = NULL,
|
||||
.cpu_present_to_apicid = default_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = NULL,
|
||||
.setup_portio_remap = NULL,
|
||||
|
||||
@@ -195,8 +195,6 @@ struct apic apic_x2apic_phys = {
|
||||
.ioapic_phys_id_map = NULL,
|
||||
.setup_apic_routing = NULL,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = NULL,
|
||||
.cpu_to_logical_apicid = NULL,
|
||||
.cpu_present_to_apicid = default_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = NULL,
|
||||
.setup_portio_remap = NULL,
|
||||
|
||||
@@ -338,8 +338,6 @@ struct apic __refdata apic_x2apic_uv_x = {
|
||||
.ioapic_phys_id_map = NULL,
|
||||
.setup_apic_routing = NULL,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = NULL,
|
||||
.cpu_to_logical_apicid = NULL,
|
||||
.cpu_present_to_apicid = default_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = NULL,
|
||||
.setup_portio_remap = NULL,
|
||||
|
||||
+32
-19
@@ -233,18 +233,22 @@ static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
|
||||
#ifdef CONFIG_NUMA
|
||||
/*
|
||||
* To workaround broken NUMA config. Read the comment in
|
||||
* srat_detect_node().
|
||||
*/
|
||||
static int __cpuinit nearby_node(int apicid)
|
||||
{
|
||||
int i, node;
|
||||
|
||||
for (i = apicid - 1; i >= 0; i--) {
|
||||
node = apicid_to_node[i];
|
||||
node = __apicid_to_node[i];
|
||||
if (node != NUMA_NO_NODE && node_online(node))
|
||||
return node;
|
||||
}
|
||||
for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
|
||||
node = apicid_to_node[i];
|
||||
node = __apicid_to_node[i];
|
||||
if (node != NUMA_NO_NODE && node_online(node))
|
||||
return node;
|
||||
}
|
||||
@@ -334,31 +338,40 @@ EXPORT_SYMBOL_GPL(amd_get_nb_id);
|
||||
|
||||
static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
|
||||
{
|
||||
#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
|
||||
#ifdef CONFIG_NUMA
|
||||
int cpu = smp_processor_id();
|
||||
int node;
|
||||
unsigned apicid = c->apicid;
|
||||
|
||||
node = per_cpu(cpu_llc_id, cpu);
|
||||
node = numa_cpu_node(cpu);
|
||||
if (node == NUMA_NO_NODE)
|
||||
node = per_cpu(cpu_llc_id, cpu);
|
||||
|
||||
if (apicid_to_node[apicid] != NUMA_NO_NODE)
|
||||
node = apicid_to_node[apicid];
|
||||
if (!node_online(node)) {
|
||||
/* Two possibilities here:
|
||||
- The CPU is missing memory and no node was created.
|
||||
In that case try picking one from a nearby CPU
|
||||
- The APIC IDs differ from the HyperTransport node IDs
|
||||
which the K8 northbridge parsing fills in.
|
||||
Assume they are all increased by a constant offset,
|
||||
but in the same order as the HT nodeids.
|
||||
If that doesn't result in a usable node fall back to the
|
||||
path for the previous case. */
|
||||
|
||||
/*
|
||||
* Two possibilities here:
|
||||
*
|
||||
* - The CPU is missing memory and no node was created. In
|
||||
* that case try picking one from a nearby CPU.
|
||||
*
|
||||
* - The APIC IDs differ from the HyperTransport node IDs
|
||||
* which the K8 northbridge parsing fills in. Assume
|
||||
* they are all increased by a constant offset, but in
|
||||
* the same order as the HT nodeids. If that doesn't
|
||||
* result in a usable node fall back to the path for the
|
||||
* previous case.
|
||||
*
|
||||
* This workaround operates directly on the mapping between
|
||||
* APIC ID and NUMA node, assuming certain relationship
|
||||
* between APIC ID, HT node ID and NUMA topology. As going
|
||||
* through CPU mapping may alter the outcome, directly
|
||||
* access __apicid_to_node[].
|
||||
*/
|
||||
int ht_nodeid = c->initial_apicid;
|
||||
|
||||
if (ht_nodeid >= 0 &&
|
||||
apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
|
||||
node = apicid_to_node[ht_nodeid];
|
||||
__apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
|
||||
node = __apicid_to_node[ht_nodeid];
|
||||
/* Pick a nearby node */
|
||||
if (!node_online(node))
|
||||
node = nearby_node(apicid);
|
||||
|
||||
@@ -869,7 +869,7 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
|
||||
|
||||
select_idle_routine(c);
|
||||
|
||||
#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
|
||||
#ifdef CONFIG_NUMA
|
||||
numa_add_cpu(smp_processor_id());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -276,14 +276,13 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
|
||||
|
||||
static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
|
||||
{
|
||||
#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
|
||||
#ifdef CONFIG_NUMA
|
||||
unsigned node;
|
||||
int cpu = smp_processor_id();
|
||||
int apicid = cpu_has_apic ? hard_smp_processor_id() : c->apicid;
|
||||
|
||||
/* Don't do the funky fallback heuristics the AMD version employs
|
||||
for now. */
|
||||
node = apicid_to_node[apicid];
|
||||
node = numa_cpu_node(cpu);
|
||||
if (node == NUMA_NO_NODE || !node_online(node)) {
|
||||
/* reuse the value from init_cpu_to_node() */
|
||||
node = cpu_to_node(cpu);
|
||||
|
||||
@@ -1047,9 +1047,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
prefill_possible_map();
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
init_cpu_to_node();
|
||||
#endif
|
||||
|
||||
init_apic_mappings();
|
||||
ioapic_and_gsi_init();
|
||||
|
||||
@@ -225,10 +225,15 @@ void __init setup_per_cpu_areas(void)
|
||||
per_cpu(x86_bios_cpu_apicid, cpu) =
|
||||
early_per_cpu_map(x86_bios_cpu_apicid, cpu);
|
||||
#endif
|
||||
#ifdef CONFIG_X86_32
|
||||
per_cpu(x86_cpu_to_logical_apicid, cpu) =
|
||||
early_per_cpu_map(x86_cpu_to_logical_apicid, cpu);
|
||||
#endif
|
||||
#ifdef CONFIG_X86_64
|
||||
per_cpu(irq_stack_ptr, cpu) =
|
||||
per_cpu(irq_stack_union.irq_stack, cpu) +
|
||||
IRQ_STACK_SIZE - 64;
|
||||
#endif
|
||||
#ifdef CONFIG_NUMA
|
||||
per_cpu(x86_cpu_to_node_map, cpu) =
|
||||
early_per_cpu_map(x86_cpu_to_node_map, cpu);
|
||||
@@ -241,7 +246,6 @@ void __init setup_per_cpu_areas(void)
|
||||
* So set them all (boot cpu and all APs).
|
||||
*/
|
||||
set_cpu_numa_node(cpu, early_cpu_to_node(cpu));
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
* Up to this point, the boot CPU has been using .init.data
|
||||
@@ -256,7 +260,10 @@ void __init setup_per_cpu_areas(void)
|
||||
early_per_cpu_ptr(x86_cpu_to_apicid) = NULL;
|
||||
early_per_cpu_ptr(x86_bios_cpu_apicid) = NULL;
|
||||
#endif
|
||||
#if defined(CONFIG_X86_64) && defined(CONFIG_NUMA)
|
||||
#ifdef CONFIG_X86_32
|
||||
early_per_cpu_ptr(x86_cpu_to_logical_apicid) = NULL;
|
||||
#endif
|
||||
#ifdef CONFIG_NUMA
|
||||
early_per_cpu_ptr(x86_cpu_to_node_map) = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -71,10 +71,6 @@
|
||||
#include <asm/smpboot_hooks.h>
|
||||
#include <asm/i8259.h>
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
u8 apicid_2_node[MAX_APICID];
|
||||
#endif
|
||||
|
||||
/* State of each CPU */
|
||||
DEFINE_PER_CPU(int, cpu_state) = { 0 };
|
||||
|
||||
@@ -136,62 +132,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
|
||||
|
||||
atomic_t init_deasserted;
|
||||
|
||||
#if defined(CONFIG_NUMA) && defined(CONFIG_X86_32)
|
||||
/* which node each logical CPU is on */
|
||||
int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
|
||||
EXPORT_SYMBOL(cpu_to_node_map);
|
||||
|
||||
/* set up a mapping between cpu and node. */
|
||||
static void map_cpu_to_node(int cpu, int node)
|
||||
{
|
||||
printk(KERN_INFO "Mapping cpu %d to node %d\n", cpu, node);
|
||||
cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
|
||||
cpu_to_node_map[cpu] = node;
|
||||
}
|
||||
|
||||
/* undo a mapping between cpu and node. */
|
||||
static void unmap_cpu_to_node(int cpu)
|
||||
{
|
||||
int node;
|
||||
|
||||
printk(KERN_INFO "Unmapping cpu %d from all nodes\n", cpu);
|
||||
for (node = 0; node < MAX_NUMNODES; node++)
|
||||
cpumask_clear_cpu(cpu, node_to_cpumask_map[node]);
|
||||
cpu_to_node_map[cpu] = 0;
|
||||
}
|
||||
#else /* !(CONFIG_NUMA && CONFIG_X86_32) */
|
||||
#define map_cpu_to_node(cpu, node) ({})
|
||||
#define unmap_cpu_to_node(cpu) ({})
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
static int boot_cpu_logical_apicid;
|
||||
|
||||
u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly =
|
||||
{ [0 ... NR_CPUS-1] = BAD_APICID };
|
||||
|
||||
static void map_cpu_to_logical_apicid(void)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
int apicid = logical_smp_processor_id();
|
||||
int node = apic->apicid_to_node(apicid);
|
||||
|
||||
if (!node_online(node))
|
||||
node = first_online_node;
|
||||
|
||||
cpu_2_logical_apicid[cpu] = apicid;
|
||||
map_cpu_to_node(cpu, node);
|
||||
}
|
||||
|
||||
void numa_remove_cpu(int cpu)
|
||||
{
|
||||
cpu_2_logical_apicid[cpu] = BAD_APICID;
|
||||
unmap_cpu_to_node(cpu);
|
||||
}
|
||||
#else
|
||||
#define map_cpu_to_logical_apicid() do {} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Report back to the Boot Processor.
|
||||
* Running on AP.
|
||||
@@ -259,7 +199,6 @@ static void __cpuinit smp_callin(void)
|
||||
apic->smp_callin_clear_local_apic();
|
||||
setup_local_APIC();
|
||||
end_local_APIC_setup();
|
||||
map_cpu_to_logical_apicid();
|
||||
|
||||
/*
|
||||
* Need to setup vector mappings before we enable interrupts.
|
||||
@@ -960,7 +899,6 @@ static __init void disable_smp(void)
|
||||
physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
|
||||
else
|
||||
physid_set_mask_of_physid(0, &phys_cpu_present_map);
|
||||
map_cpu_to_logical_apicid();
|
||||
cpumask_set_cpu(0, cpu_sibling_mask(0));
|
||||
cpumask_set_cpu(0, cpu_core_mask(0));
|
||||
}
|
||||
@@ -1096,9 +1034,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
|
||||
* Setup boot CPU information
|
||||
*/
|
||||
smp_store_cpu_info(0); /* Final full version of the data */
|
||||
#ifdef CONFIG_X86_32
|
||||
boot_cpu_logical_apicid = logical_smp_processor_id();
|
||||
#endif
|
||||
|
||||
current_thread_info()->cpu = 0; /* needed? */
|
||||
for_each_possible_cpu(i) {
|
||||
zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
|
||||
@@ -1139,8 +1075,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
|
||||
|
||||
end_local_APIC_setup();
|
||||
|
||||
map_cpu_to_logical_apicid();
|
||||
|
||||
if (apic->setup_portio_remap)
|
||||
apic->setup_portio_remap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user