Andi,
Please check the patch regarding apicid lifting.
For some reason, we need to lift AP apicid but keep the BSP apicid to 0....
Also it solve the E0 later single but have apic id reorder problem...
YH
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -786,13 +786,24 @@ static void __init amd_detect_cmp(struct
#ifdef CONFIG_SMP
int cpu = smp_processor_id();
unsigned bits;
+ int cores_vir;
#ifdef CONFIG_NUMA
int node = 0;
- unsigned apicid = phys_proc_id[cpu];
+ unsigned initial_apicid = phys_proc_id[cpu];
+ unsigned apicid = hard_smp_processor_id();
#endif
+
+ cores_vir = c->x86_max_cores;
+ if(cores_vir == 1) {
+ unsigned level = cpuid_eax(1);
+ /* double check if it is E0 later, only E0 later can reorder apicid
for single core */
+ if ((level & 0xf0f00) >= 0x20f00) {
+ cores_vir = 2;
+ }
+ }
bits = 0;
- while ((1 << bits) < c->x86_max_cores)
+ while ((1 << bits) < cores_vir)
bits++;
/* Low order bits define the core id (index of core in socket) */
@@ -802,32 +813,23 @@ static void __init amd_detect_cmp(struct
#ifdef CONFIG_NUMA
node = phys_proc_id[cpu];
- if (apicid_to_node[apicid] != NUMA_NO_NODE)
- node = apicid_to_node[apicid];
+
+ if (apicid_to_node[apicid] == NUMA_NO_NODE)
+ apicid_to_node[apicid] = node;
+
if (!node_online(node)) {
- /* Two possibilities here:
+ /* One 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. */
- int ht_nodeid = apicid - (phys_proc_id[0] << bits);
- if (ht_nodeid >= 0 &&
- 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);
+ In that case try picking one from a nearby CPU */
+ node = nearby_node(apicid);
}
+
numa_set_node(cpu, node);
+#endif
printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
cpu, c->x86_max_cores, node, cpu_core_id[cpu]);
#endif
-#endif
}
static int __init init_amd(struct cpuinfo_x86 *c)