@@ -68,6 +68,10 @@ static inline bool arch_numa_broken(void)
return true;
}
+static inline void numa_set_node(unsigned int cpu, nodeid_t node)
+{
+}
+
#endif
#define arch_want_default_dmazone() (false)
@@ -119,7 +119,12 @@ static void __init dt_smp_init_cpus(void)
{
[0 ... NR_CPUS - 1] = MPIDR_INVALID
};
+ static nodeid_t node_map[NR_CPUS] __initdata =
+ {
+ [0 ... NR_CPUS - 1] = NUMA_NO_NODE
+ };
bool bootcpu_valid = false;
+ unsigned int nid = 0;
int rc;
mpidr = system_cpuinfo.mpidr.bits & MPIDR_HWID_MASK;
@@ -170,6 +175,28 @@ static void __init dt_smp_init_cpus(void)
continue;
}
+ if ( IS_ENABLED(CONFIG_NUMA) )
+ {
+ /*
+ * When CONFIG_NUMA is set, try to fetch numa infomation
+ * from CPU dts node, otherwise the nid is always 0.
+ */
+ if ( !dt_property_read_u32(cpu, "numa-node-id", &nid) )
+ {
+ printk(XENLOG_WARNING
+ "cpu[%d] dts path: %s: doesn't have numa information!\n",
+ cpuidx, dt_node_full_name(cpu));
+ /*
+ * During the early stage of NUMA initialization, when Xen
+ * found any CPU dts node doesn't have numa-node-id info, the
+ * NUMA will be treated as off, all CPU will be set to a FAKE
+ * node 0. So if we get numa-node-id failed here, we should
+ * set nid to 0.
+ */
+ nid = 0;
+ }
+ }
+
/*
* 8 MSBs must be set to 0 in the DT since the reg property
* defines the MPIDR[23:0]
@@ -229,9 +256,13 @@ static void __init dt_smp_init_cpus(void)
{
printk("cpu%d init failed (hwid %"PRIregister"): %d\n", i, hwid, rc);
tmp_map[i] = MPIDR_INVALID;
+ node_map[i] = NUMA_NO_NODE;
}
else
+ {
tmp_map[i] = hwid;
+ node_map[i] = nid;
+ }
}
if ( !bootcpu_valid )
@@ -247,6 +278,11 @@ static void __init dt_smp_init_cpus(void)
continue;
cpumask_set_cpu(i, &cpu_possible_map);
cpu_logical_map(i) = tmp_map[i];
+
+ nid = node_map[i];
+ if ( nid >= MAX_NUMNODES )
+ nid = 0;
+ numa_set_node(i, nid);
}
}