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

[PATCH 06/21] xen/device-tree: Read NUMA node distance from Device Tree 'distance-map'


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Hirokazu Takahashi <taka@xxxxxxxxxxxxx>
  • Date: Sun, 24 May 2026 09:01:54 +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=efsYPuOFBJuGq5l6y14uP1QzlvYcMA2MZ/bYJIg+6Cc=; b=ZW5gvFYg8G0deOojXSXDIAgILOC2eSY9FIaTE0FNZmhFkUe+o/A0cp0EPhyZNpCEdT+IK3vkQ8bE6oRfgxl2JXqiwD6eNARXI91L4++4jWJxDcUxmO/DlCpcdCYZBEnoTJft6gzk13fdpHUiOXh6kA/SYSkLmy+QP/t0YY5JUAChTGnyO/KtxFtpYnVtXJKvZH+fVdKlE4i67w1Y7Y5MsW1jffTQi1ATgUhPTiYTQG5QOUMQ6/+PnGWPDQGTByt8SiB9Ke1DFeqM9b8B88E5TXkJPtx+BwySiTph5xjpi2xATVsSXSEEte5InoNZiShUt7sB7zv+Se6PIQ4GJqLi+A==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=CSNGXx45uWjRTdCWHP8vu0hNHuNQyJC4CKyRFibAR36on88tH5kPem342E2r9gyPHjCdBULx/Jrdj3uO0D+m3XbuwXPtb7KGqnLPPWwwgXjnYduQ5aqcP9J53y4HVONSmtyQN2TADeZKTERZNebVG14O/EbAiTgLs344E1AHIAVLZUUtISePCt4tEPBsRQGK0G91dDKBXOpZqGVN7sSILEoTruM31TeBKvM8o89ggnuQd1u72HqoaVsH4CMGBJRMoIdbBHC8xLiFbJEH0lBma/luD9zs+4roGvDibEOgquic8b5+/hR0d9cBliK8zIzsebNOmr3iYJWT4XPpl2Z0rg==
  • 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: andrew.cooper3@xxxxxxxxxx, anthony.perard@xxxxxxxxxx, michal.orzel@xxxxxxx, jbeulich@xxxxxxxx, julien@xxxxxxx, roger.pau@xxxxxxxxxx, sstabellini@xxxxxxxxxx, jgross@xxxxxxxx, bertrand.marquis@xxxxxxx, Volodymyr_Babchuk@xxxxxxxx, dfaggioli@xxxxxxxx, gwd@xxxxxxxxxxxxxx, Hirokazu Takahashi <taka@xxxxxxxxxxxxx>
  • Delivery-date: Sun, 24 May 2026 00:02:45 +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.
---
 xen/arch/arm/numa.c           |  2 +
 xen/common/device-tree/numa.c | 93 ++++++++++++++++++++++++++++++++++-
 xen/include/xen/dt-numa.h     |  1 +
 3 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/numa.c b/xen/arch/arm/numa.c
index 15cad3d267..a7769b0c7d 100644
--- a/xen/arch/arm/numa.c
+++ b/xen/arch/arm/numa.c
@@ -41,6 +41,8 @@ void __init numa_memory_affinity_init(void)
     dt_numa_memory_affinity_init();
 
     numa_initmem_init(0x0UL, 0x1UL << (PADDR_BITS - 12));
+
+    dt_numa_distance_table_init();
 }
 
 int __init arch_get_ram_range(unsigned int idx, paddr_t *start, paddr_t *end)
diff --git a/xen/common/device-tree/numa.c b/xen/common/device-tree/numa.c
index 539ddfccc5..6414806937 100644
--- a/xen/common/device-tree/numa.c
+++ b/xen/common/device-tree/numa.c
@@ -1,4 +1,11 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Derived from Linux kernel 7.0's $drivers/of/of_numa.c
+ * Parse 'distance-map'
+ *
+ * Copyright (c) 2026 VA Linux Systems Japan K.K.
+ * Author: Hirokazu Takahashi <taka@xxxxxxxxxxxxx>
+ */
 
 #include <xen/bootinfo.h>
 #include <xen/device_tree.h>
@@ -12,14 +19,96 @@
 #define LOCAL_DISTANCE      10
 #define REMOTE_DISTANCE     20
 
+static u8 __ro_after_init numa_distance[MAX_NUMNODES][MAX_NUMNODES] = {
+    [0 ... MAX_NUMNODES-1][0 ... MAX_NUMNODES-1] = NUMA_NO_DISTANCE
+};
+
 /*
  * Get the distance between node 'a' and node 'b'.
  */
 u8 dt_node_distance(u8 a, u8 b)
 {
-    if ( a != b )
+    nodeid_t lastnode = last_node(node_online_map);
+
+    if (a > lastnode || b > lastnode)
         return REMOTE_DISTANCE;
-    return LOCAL_DISTANCE;
+
+    return numa_distance[a][b];
+}
+
+static void __init numa_set_distance(u8 from, u8 to, u8 distance)
+{
+    nodeid_t lastnode = last_node(node_online_map);
+
+    if (from <= lastnode && to <= lastnode)
+        numa_distance[from][to] = distance;
+}
+
+/*
+ * 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)
+    {
+        u32 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)
+{
+    u32 lastnode = last_node(node_online_map);
+    u32 i, j;
+
+    /* fill with the default distances */
+    for (i = 0U; i <= lastnode; i++)
+        for (j = 0U; j <= lastnode; j++)
+            numa_distance[i][j] = i == j ? LOCAL_DISTANCE : REMOTE_DISTANCE;
+
+    dt_numa_parse_distance_map();
 }
 
 /*
diff --git a/xen/include/xen/dt-numa.h b/xen/include/xen/dt-numa.h
index c6939d0928..075d31cb89 100644
--- a/xen/include/xen/dt-numa.h
+++ b/xen/include/xen/dt-numa.h
@@ -15,6 +15,7 @@ static inline unsigned int numa_node_to_dt_nid(u32 n)
 
 u8 dt_node_distance(u8 a, u8 b);
 void dt_numa_memory_affinity_init(void);
+void dt_numa_distance_table_init(void);
 
 #endif /* CONFIG_DEVICE_TREE_NUMA */
 
-- 
2.43.0




 


Rackspace

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