All of lore.kernel.org
 help / color / mirror / Atom feed
From: Henry Wang <Henry.Wang@arm.com>
To: xen-devel@lists.xenproject.org
Cc: Wei Chen <wei.chen@arm.com>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Julien Grall <julien@xen.org>,
	Bertrand Marquis <bertrand.marquis@arm.com>,
	Michal Orzel <michal.orzel@amd.com>,
	Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>,
	Henry Wang <Henry.Wang@arm.com>
Subject: [PATCH v6 09/17] xen/arm: introduce a helper to parse device tree NUMA distance map
Date: Mon, 20 Nov 2023 10:54:23 +0800	[thread overview]
Message-ID: <20231120025431.14845-10-Henry.Wang@arm.com> (raw)
In-Reply-To: <20231120025431.14845-1-Henry.Wang@arm.com>

From: Wei Chen <wei.chen@arm.com>

A NUMA aware device tree will provide a "distance-map" node to
describe distance between any two nodes. This patch introduce a
new helper to parse this distance map.

Note that, since the NUMA device tree binding does not explicitly
specify the range of valid node distance, hence rather than
rejecting node distance values >= 0xff, saturate the distance at
0xfe, while keeping 0xff for NUMA_NO_DISTANCE, so overall we can
keep things consistent with ACPI.

Signed-off-by: Wei Chen <wei.chen@arm.com>
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
---
v5 -> v6:
- Rebase on top of staging without code changes.
v1 -> v5:
- Fix coding style (printk variable type and label indented) and
  in-code comment.
- Check the from/to range to avoid the side-effect of the 8-bit
  truncation by numa_set_distance().
- The distance map default value is now NUMA_NO_DISTANCE, update
  the logic accordingly and add in-code comment as a note.
- Get rid of useless braces.
- Use new NUMA status helper.
- Use PRIu32 to replace u in print messages.
- Fix opposite = __node_distance(to, from).
- disable dtb numa info table when we find an invalid data in dtb.
---
 xen/arch/arm/numa-dt.c | 116 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)

diff --git a/xen/arch/arm/numa-dt.c b/xen/arch/arm/numa-dt.c
index cebc7e4300..2fb6663e08 100644
--- a/xen/arch/arm/numa-dt.c
+++ b/xen/arch/arm/numa-dt.c
@@ -151,3 +151,119 @@ static int __init fdt_parse_numa_memory_node(const void *fdt, int node,
     numa_fw_bad();
     return -EINVAL;
 }
+
+/* Parse NUMA distance map v1 */
+static int __init fdt_parse_numa_distance_map_v1(const void *fdt, int node)
+{
+    const struct fdt_property *prop;
+    const __be32 *matrix;
+    unsigned int i, entry_count;
+    int len;
+
+    printk(XENLOG_INFO "NUMA: parsing numa-distance-map\n");
+
+    prop = fdt_get_property(fdt, node, "distance-matrix", &len);
+    if ( !prop )
+    {
+        printk(XENLOG_WARNING
+               "NUMA: No distance-matrix property in distance-map\n");
+        goto invalid_data;
+    }
+
+    if ( len % sizeof(__be32) != 0 )
+    {
+        printk(XENLOG_WARNING
+               "distance-matrix in node is not a multiple of u32\n");
+        goto invalid_data;
+    }
+
+    entry_count = len / sizeof(__be32);
+    if ( entry_count == 0 )
+    {
+        printk(XENLOG_WARNING "NUMA: Invalid distance-matrix\n");
+        goto invalid_data;
+    }
+
+    matrix = (const __be32 *)prop->data;
+    for ( i = 0; i + 2 < entry_count; i += 3 )
+    {
+        unsigned int from, to, distance, opposite;
+
+        from = dt_next_cell(1, &matrix);
+        to = dt_next_cell(1, &matrix);
+        distance = dt_next_cell(1, &matrix);
+
+        if ( from >= MAX_NUMNODES || to >= MAX_NUMNODES )
+        {
+            printk(XENLOG_WARNING "NUMA: invalid nodes: from=%u to=%u MAX=%u\n",
+                   from, to, MAX_NUMNODES);
+            goto invalid_data;
+        }
+
+        if ( (from == to && distance != NUMA_LOCAL_DISTANCE) ||
+             (from != to && distance <= NUMA_LOCAL_DISTANCE) )
+        {
+            printk(XENLOG_WARNING
+                   "NUMA: Invalid distance: NODE#%u->NODE#%u:%u\n",
+                   from, to, distance);
+            goto invalid_data;
+        }
+
+        printk(XENLOG_INFO "NUMA: distance: NODE#%u->NODE#%u:%u\n",
+               from, to, distance);
+
+        /* Get opposite way distance */
+        opposite = __node_distance(to, from);
+        /* The default value in node_distance_map is NUMA_NO_DISTANCE */
+        if ( opposite == NUMA_NO_DISTANCE )
+        {
+            /* Bi-directions are not set, set both */
+            numa_set_distance(from, to, distance);
+            numa_set_distance(to, from, distance);
+        }
+        else
+        {
+            /*
+             * Opposite way distance has been set to a different value.
+             * It may be a firmware device tree bug?
+             */
+            if ( opposite != distance )
+            {
+                /*
+                 * In device tree NUMA distance-matrix binding:
+                 * https://www.kernel.org/doc/Documentation/devicetree/bindings/numa.txt
+                 * There is a notes mentions:
+                 * "Each entry represents distance from first node to
+                 *  second node. The distances are equal in either
+                 *  direction."
+                 *
+                 * That means device tree doesn't permit this case.
+                 * But in ACPI spec, it cares to specifically permit this
+                 * case:
+                 * "Except for the relative distance from a System Locality
+                 *  to itself, each relative distance is stored twice in the
+                 *  matrix. This provides the capability to describe the
+                 *  scenario where the relative distances for the two
+                 *  directions between System Localities is different."
+                 *
+                 * That means a real machine allows such NUMA configuration.
+                 * So, place a WARNING here to notice system administrators,
+                 * is it the special case that they hijack the device tree
+                 * to support their rare machines?
+                 */
+                printk(XENLOG_WARNING
+                       "Un-matched bi-direction! NODE#%u->NODE#%u:%u, NODE#%u->NODE#%u:%u\n",
+                       from, to, distance, to, from, opposite);
+            }
+
+            /* Opposite way distance was set before, just set this way */
+            numa_set_distance(from, to, distance);
+        }
+    }
+
+    return 0;
+
+ invalid_data:
+    numa_fw_bad();
+    return -EINVAL;
+}
-- 
2.25.1



  parent reply	other threads:[~2023-11-20  2:56 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-20  2:54 [PATCH v6 00/17] Device tree based NUMA support for Arm Henry Wang
2023-11-20  2:54 ` [PATCH v6 01/17] xen/arm: use NR_MEM_BANKS to override default NR_NODE_MEMBLKS Henry Wang
2023-11-20  2:54 ` [PATCH v6 02/17] xen/arm: implement helpers to get and update NUMA status Henry Wang
2024-01-03 15:10   ` Julien Grall
2023-11-20  2:54 ` [PATCH v6 03/17] xen/arm: implement node distance helpers for Arm Henry Wang
2023-11-20  2:54 ` [PATCH v6 04/17] xen/arm: use arch_get_ram_range to get memory ranges from bootinfo Henry Wang
2023-11-20  2:54 ` [PATCH v6 05/17] xen/arm: build NUMA cpu_to_node map in dt_smp_init_cpus Henry Wang
2023-11-20  2:54 ` [PATCH v6 06/17] xen/arm: Add boot and secondary CPU to NUMA system Henry Wang
2023-11-20  2:54 ` [PATCH v6 07/17] xen/arm: introduce a helper to parse device tree processor node Henry Wang
2023-11-20  2:54 ` [PATCH v6 08/17] xen/arm: introduce a helper to parse device tree memory node Henry Wang
2023-11-20  2:54 ` Henry Wang [this message]
2023-11-20  2:54 ` [PATCH v6 10/17] xen/arm: unified entry to parse all NUMA data from device tree Henry Wang
2023-11-20  2:54 ` [PATCH v6 11/17] xen/arm: keep guest still be NUMA unware Henry Wang
2023-11-20  2:54 ` [PATCH v6 12/17] xen/arm: enable device tree based NUMA in system init Henry Wang
2023-11-20  2:54 ` [PATCH v6 13/17] xen/arm: implement numa_node_to_arch_nid for device tree NUMA Henry Wang
2023-11-20  2:54 ` [PATCH v6 14/17] xen/arm: use CONFIG_NUMA to gate node_online_map in smpboot Henry Wang
2023-11-20  2:54 ` [PATCH v6 15/17] xen/arm: Set correct per-cpu cpu_core_mask Henry Wang
2023-11-20  2:54 ` [PATCH v6 16/17] xen/arm: Provide Kconfig options for Arm to enable NUMA Henry Wang
2023-11-20  2:54 ` [PATCH v6 17/17] docs: update numa command line to support Arm Henry Wang
2023-11-20  8:55   ` Jan Beulich
2023-11-20  8:57     ` Henry Wang
2023-11-30  1:06 ` [PATCH v6 00/17] Device tree based NUMA support for Arm Stefano Stabellini
2023-11-30  2:11   ` Henry Wang
2024-01-03 15:14 ` Julien Grall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231120025431.14845-10-Henry.Wang@arm.com \
    --to=henry.wang@arm.com \
    --cc=Volodymyr_Babchuk@epam.com \
    --cc=bertrand.marquis@arm.com \
    --cc=julien@xen.org \
    --cc=michal.orzel@amd.com \
    --cc=sstabellini@kernel.org \
    --cc=wei.chen@arm.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.