[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v3 07/22] xen/device-tree: Read NUMA node distance from Device Tree 'distance-map'


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Hirokazu Takahashi <taka@xxxxxxxxxxxxx>
  • Date: Fri, 19 Jun 2026 16:49:55 +0900
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=valinux.co.jp; dmarc=pass action=none header.from=valinux.co.jp; dkim=pass header.d=valinux.co.jp; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=rCZMtyLGMNYzHusbpyFyHoil1cfalWfsKDDSBtV0qlk=; b=wS2b3bW43j5lnVTFpyl/tJQW61lm7HtwfLG2CcrRKPMg7OApOXW+9Ua+rrgSfyffGzw7zRsS4mmThrScJ7y2ntlRbeTp9oUH2nF7+2umNfzqsPpcnue9rI5D16gFWqIa5o1nLuQXSN4phtYECzvwKePk1t3WSs2lAzpdXfQn24fEqW4i3Gjlp4iyCe+fET6NKfey3hF1lIqwMdk1ESy6PmoyIjw+59jKSdNy6szwLgVFCzjUP15Sx8KbTKPomAwbT8xUiEdN2poT6ln6yEpc54za4EzU62nlOiECwlFqUVDdNjMoTaYkphB0+Bca5VYlkpTf7S2st6YEBKkrCpehMw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=H7qNTgP1KevvChwSYbz1tA8C5G76ZnqB85+tfWai3TutK+u/BkmWLHjwRbuf9IUJtI70vNMq2QU9TJTtewcYSWRG4IpXNigekxiB/g4k8ravQAhL8NoS3ZapNrjP1wDqHBZjp4a05t5XjvQR6oaSSlWU99kmq6499ZZZCpkU3jlEgm9/NQk7IHRL7vCPPvsXHs95Kf28UuycN31Zm7D7+iuRW8iY3iE9c+DM1sfWjl3VMcCpuPSD6pzF7qSsj27C1xxWDusYihIrxTRntS5DuSXJUF/2rwRu+DEqXg04NCUUayMuZR3aW9HE2LnH87PTW3MpswDz8LL+RI+zfVtX0Q==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=valinux.co.jp header.i="@valinux.co.jp" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=valinux.co.jp;
  • Cc: Hirokazu Takahashi <taka@xxxxxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Fri, 19 Jun 2026 07:50:38 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Read the distance between NUMA nodes from the Device Tree's
'distance-map' node.

Signed-off-by: Hirokazu Takahashi <taka@xxxxxxxxxxxxx>
---
 xen/arch/arm/setup.c           |  4 ++
 xen/common/device-tree/numa.c  | 76 ++++++++++++++++++++++++++++++++++
 xen/common/numa-distance-map.c | 49 ++++++++++++++++++++--
 xen/include/xen/dt-numa.h      |  1 +
 xen/include/xen/numa.h         |  5 +++
 5 files changed, 132 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index cdabf536b0..cf12c406fc 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -375,6 +375,10 @@ void asmlinkage __init noreturn start_xen(unsigned long 
fdt_paddr)
         device_tree_flattened = NULL;
     }
 
+#ifdef CONFIG_NUMA
+    numa_distance_table_init();
+#endif /* CONFIG_NUMA */
+
     init_IRQ();
 
     platform_init();
diff --git a/xen/common/device-tree/numa.c b/xen/common/device-tree/numa.c
index ff5a7dee9a..3dd608b599 100644
--- a/xen/common/device-tree/numa.c
+++ b/xen/common/device-tree/numa.c
@@ -1,4 +1,80 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Derived from Linux kernel 7.0's $drivers/of/of_numa.c
+ * Parse 'distance-map'
+ */
+
+#include <xen/bootinfo.h>
+#include <xen/device_tree.h>
+#include <xen/libfdt/libfdt.h>
+#include <xen/bootfdt.h>
+#include <xen/errno.h>
+#include <xen/init.h>
+#include <xen/nodemask.h>
+#include <xen/numa.h>
+
+#define LOCAL_DISTANCE      10
+#define REMOTE_DISTANCE     20
+
+/*
+ * Parse the '/distance-map' node from the flattened device tree
+ * and extract the 3-tuple triplets <from, to, distance>.
+ */
+static void __init dt_numa_parse_distance_map(void)
+{
+    const void *fdt = device_tree_flattened;
+    const struct fdt_property *prop;
+    const __be32 *matrix;
+    int entry_count;
+    int node;
+    int len;
+    int i;
+
+    node = fdt_path_offset(fdt, "/distance-map");
+    if ( node < 0 )
+        return;
+
+    if ( fdt_node_check_compatible(fdt, node, "numa-distance-map-v1") )
+        return;
+
+    prop = fdt_get_property(fdt, node, "distance-matrix", &len);
+    if ( !prop )
+        return;
+
+    matrix = (const __be32*)prop->data;
+    entry_count = len / sizeof(__be32);
+
+    if ( (entry_count <= 0) || (entry_count % 3) )
+        return;
+
+    for ( i = 0; i + 2 < entry_count; i += 3 )
+    {
+        uint32_t nodea, nodeb, distance;
+
+        nodea = dt_next_cell(1, &matrix);
+        nodeb = dt_next_cell(1, &matrix);
+        distance = dt_next_cell(1, &matrix);
+
+        if ( (nodea == nodeb && distance != LOCAL_DISTANCE) ||
+             (nodea != nodeb && distance <= LOCAL_DISTANCE) )
+        {
+            printk(XENLOG_WARNING "Invalid distance[node%d -> node%d] = %d\n",
+                   nodea, nodeb, distance);
+            continue;
+        }
+
+        numa_set_distance(nodea, nodeb, distance);
+
+        /* Set default distance of node B->A same as A->B */
+        if ( nodeb > nodea )
+            numa_set_distance(nodeb, nodea, distance);
+    }
+}
+
+void __init dt_numa_distance_table_init(void)
+{
+    dt_numa_parse_distance_map();
+}
 
 /*
  * Initialize memory affinity by registering bootinfo memory banks into Xen's
diff --git a/xen/common/numa-distance-map.c b/xen/common/numa-distance-map.c
index 73344f7f33..6e68912646 100644
--- a/xen/common/numa-distance-map.c
+++ b/xen/common/numa-distance-map.c
@@ -1,19 +1,62 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Derived from Linux kernel 7.0's $mm/numa_memblks.c
+ */
 
 #include <xen/errno.h>
 #include <xen/init.h>
 #include <xen/nodemask.h>
 #include <xen/numa.h>
+#include <xen/acpi.h>
+
 
 #define LOCAL_DISTANCE      10
 #define REMOTE_DISTANCE     20
 
+uint8_t * __ro_after_init numa_distance;
+
 /*
  * Get the distance between node 'from' and node 'to'.
  */
 uint8_t numa_node_distance(unsigned int from, unsigned int to)
 {
-    if ( from != to )
-        return REMOTE_DISTANCE;
-    return LOCAL_DISTANCE;
+    const unsigned int nr_nodes = last_node(node_online_map) + 1U;
+
+    if ( from >= nr_nodes || to >= nr_nodes )
+        return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
+
+    return numa_distance[from * nr_nodes + to];
+}
+
+void __init numa_set_distance(unsigned int from, unsigned int to,
+                                     unsigned int distance)
+{
+    const unsigned int nr_nodes = last_node(node_online_map) + 1U;
+
+    if ( (uint8_t)distance != distance || from >= nr_nodes || to >= nr_nodes )
+        printk(XENLOG_WARNING "Invalid distance[node%d -> node%d] = %d\n",
+               from, to, distance);
+    else
+        numa_distance[from * nr_nodes + to] = distance;
+}
+
+void __init numa_distance_table_init(void)
+{
+    const unsigned int nr_nodes = last_node(node_online_map) + 1U;
+    unsigned int i, j;
+
+    numa_distance = xzalloc_array(uint8_t, nr_nodes * nr_nodes);
+    if ( !numa_distance )
+        panic("Failed to allocate memory for numa distance-map array\n");
+
+    /* fill with the default distances */
+    for ( i = 0U; i < nr_nodes; i++ )
+        for ( j = 0U; j < nr_nodes; j++ )
+            numa_distance[i * nr_nodes + j] = i == j ?
+                LOCAL_DISTANCE : REMOTE_DISTANCE;
+
+    if ( acpi_disabled )
+        dt_numa_distance_table_init();
+    else
+        ; /* Initialize the distance-map array with ACPI SLIT */
 }
diff --git a/xen/include/xen/dt-numa.h b/xen/include/xen/dt-numa.h
index 943bc0e453..352853dd81 100644
--- a/xen/include/xen/dt-numa.h
+++ b/xen/include/xen/dt-numa.h
@@ -14,6 +14,7 @@ static inline unsigned int numa_node_to_dt_nid(unsigned int n)
 #ifdef CONFIG_DEVICE_TREE_NUMA
 
 void dt_numa_memory_affinity_init(void);
+void dt_numa_distance_table_init(void);
 
 #endif /* CONFIG_DEVICE_TREE_NUMA */
 
diff --git a/xen/include/xen/numa.h b/xen/include/xen/numa.h
index 18c22d3d30..e7201539d1 100644
--- a/xen/include/xen/numa.h
+++ b/xen/include/xen/numa.h
@@ -129,6 +129,11 @@ extern bool numa_update_node_memblks(nodeid_t node, 
unsigned int arch_nid,
 extern void numa_set_processor_nodes_parsed(nodeid_t node);
 
 extern uint8_t numa_node_distance(unsigned int from, unsigned int to);
+extern void numa_set_distance(unsigned int from, unsigned int to,
+                              unsigned int distance);
+extern void numa_distance_table_init(void);
+
+extern uint8_t *numa_distance;
 
 #else
 
-- 
2.43.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.