diff mbox

[RFC,v2,13/25] ARM: NUMA: Parse memory NUMA information

Message ID 1490716413-19796-14-git-send-email-vijay.kilari@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vijay Kilari March 28, 2017, 3:53 p.m. UTC
From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>

Parse memory node and fetch numa-node-id information.
For each memory range, store in node_memblk_range[]
along with node id.

When booting in UEFI mode, UEFI passes memory information
to Dom0 using EFI memory descriptor table and deletes the
memory nodes from the host DT. However to fetch the memory
numa node id, memory DT node should not be deleted by EFI stub.
With this patch, do not delete memory node from FDT.

NUMA info of memory is extracted from process_memory_node()
instead of parsing the DT again during numa_init().

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
---
 xen/arch/arm/bootfdt.c      | 24 ++++++++++++++++++++----
 xen/arch/arm/efi/efi-boot.h | 25 -------------------------
 xen/arch/arm/numa/dt_numa.c | 33 +++++++++++++++++++++++++++++++++
 xen/arch/arm/numa/numa.c    |  9 +++++++++
 xen/include/asm-arm/numa.h  |  2 ++
 5 files changed, 64 insertions(+), 29 deletions(-)
diff mbox

Patch

diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
index 1f876f0..993760a 100644
--- a/xen/arch/arm/bootfdt.c
+++ b/xen/arch/arm/bootfdt.c
@@ -13,6 +13,7 @@ 
 #include <xen/init.h>
 #include <xen/device_tree.h>
 #include <xen/libfdt/libfdt.h>
+#include <xen/efi.h>
 #include <xsm/xsm.h>
 #include <asm/setup.h>
 
@@ -146,6 +147,9 @@  static void __init process_memory_node(const void *fdt, int node,
     const __be32 *cell;
     paddr_t start, size;
     u32 reg_cells = address_cells + size_cells;
+#ifdef CONFIG_NUMA
+    uint32_t nid;
+#endif
 
     if ( address_cells < 1 || size_cells < 1 )
     {
@@ -154,24 +158,36 @@  static void __init process_memory_node(const void *fdt, int node,
         return;
     }
 
+#ifdef CONFIG_NUMA
+    nid = device_tree_get_u32(fdt, node, "numa-node-id", NR_NODE_MEMBLKS);
+#endif
     prop = fdt_get_property(fdt, node, "reg", NULL);
     if ( !prop )
     {
         printk("fdt: node `%s': missing `reg' property\n", name);
+#ifdef CONFIG_NUMA
+	numa_failed();
+#endif
         return;
     }
 
     cell = (const __be32 *)prop->data;
     banks = fdt32_to_cpu(prop->len) / (reg_cells * sizeof (u32));
 
-    for ( i = 0; i < banks && bootinfo.mem.nr_banks < NR_MEM_BANKS; i++ )
+    for ( i = 0; i < banks; i++ )
     {
         device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
         if ( !size )
             continue;
-        bootinfo.mem.bank[bootinfo.mem.nr_banks].start = start;
-        bootinfo.mem.bank[bootinfo.mem.nr_banks].size = size;
-        bootinfo.mem.nr_banks++;
+        if ( !efi_enabled(EFI_BOOT) && bootinfo.mem.nr_banks < NR_MEM_BANKS )
+        {
+            bootinfo.mem.bank[bootinfo.mem.nr_banks].start = start;
+            bootinfo.mem.bank[bootinfo.mem.nr_banks].size = size;
+            bootinfo.mem.nr_banks++;
+        }
+#ifdef CONFIG_NUMA
+        dt_numa_process_memory_node(nid, start, size);
+#endif
     }
 }
 
diff --git a/xen/arch/arm/efi/efi-boot.h b/xen/arch/arm/efi/efi-boot.h
index e1e447a..07fe178 100644
--- a/xen/arch/arm/efi/efi-boot.h
+++ b/xen/arch/arm/efi/efi-boot.h
@@ -194,33 +194,8 @@  EFI_STATUS __init fdt_add_uefi_nodes(EFI_SYSTEM_TABLE *sys_table,
     int status;
     u32 fdt_val32;
     u64 fdt_val64;
-    int prev;
     int num_rsv;
 
-    /*
-     * Delete any memory nodes present.  The EFI memory map is the only
-     * memory description provided to Xen.
-     */
-    prev = 0;
-    for (;;)
-    {
-        const char *type;
-        int len;
-
-        node = fdt_next_node(fdt, prev, NULL);
-        if ( node < 0 )
-            break;
-
-        type = fdt_getprop(fdt, node, "device_type", &len);
-        if ( type && strncmp(type, "memory", len) == 0 )
-        {
-            fdt_del_node(fdt, node);
-            continue;
-        }
-
-        prev = node;
-    }
-
    /*
     * Delete all memory reserve map entries. When booting via UEFI,
     * kernel will use the UEFI memory map to find reserved regions.
diff --git a/xen/arch/arm/numa/dt_numa.c b/xen/arch/arm/numa/dt_numa.c
index 66c6efb..593c647 100644
--- a/xen/arch/arm/numa/dt_numa.c
+++ b/xen/arch/arm/numa/dt_numa.c
@@ -25,6 +25,7 @@ 
 #include <asm/setup.h>
 
 extern nodemask_t processor_nodes_parsed;
+extern nodemask_t memory_nodes_parsed;
 
 /*
  * Even though we connect cpus to numa domains later in SMP
@@ -59,6 +60,38 @@  static int __init dt_numa_scan_cpu_node(const void *fdt, int node,
     return 0;
 }
 
+void __init dt_numa_process_memory_node(uint32_t nid, paddr_t start,
+                                       paddr_t size)
+{
+    struct node *nd;
+    int i;
+
+    i = conflicting_memblks(start, start + size);
+    if ( i < 0 )
+    {
+         if ( numa_add_memblk(nid, start, size) )
+         {
+             printk(XENLOG_WARNING "DT: NUMA: node-id %u overflow \n", nid);
+             numa_failed();
+             return;
+         }
+    }
+    else
+    {
+         nd = get_node_memblk_range(i);
+         printk(XENLOG_ERR
+                "NUMA DT: node %u (%"PRIx64"-%"PRIx64") overlaps with %d (%"PRIx64"-%"PRIx64")\n",
+                nid, start, start + size, i, nd->start, nd->end);
+
+         numa_failed();
+         return;
+    }
+
+    node_set(nid, memory_nodes_parsed);
+
+    return;
+}
+
 int __init dt_numa_init(void)
 {
     int ret;
diff --git a/xen/arch/arm/numa/numa.c b/xen/arch/arm/numa/numa.c
index c1c7c35..b333453 100644
--- a/xen/arch/arm/numa/numa.c
+++ b/xen/arch/arm/numa/numa.c
@@ -23,6 +23,12 @@ 
 #include <asm/acpi.h>
 
 extern nodemask_t processor_nodes_parsed;
+static bool_t dt_numa = 1;
+
+void numa_failed(void)
+{
+    dt_numa = 0;
+}
 
 void __init numa_init(void)
 {
@@ -32,6 +38,9 @@  void __init numa_init(void)
     if ( is_numa_off() )
         goto no_numa;
 
+    if ( !dt_numa )
+        goto no_numa;
+
     ret = dt_numa_init();
     if ( ret )
         printk(XENLOG_WARNING "DT NUMA init failed\n");
diff --git a/xen/include/asm-arm/numa.h b/xen/include/asm-arm/numa.h
index e50ee19..962a214 100644
--- a/xen/include/asm-arm/numa.h
+++ b/xen/include/asm-arm/numa.h
@@ -6,6 +6,8 @@  typedef uint8_t nodeid_t;
 /* Limit number of NUMA nodes supported to 4 */
 #define NODES_SHIFT 2
 
+extern void dt_numa_process_memory_node(uint32_t nid,paddr_t start,
+                                        paddr_t size);
 #ifdef CONFIG_NUMA
 extern void numa_init(void);
 extern int dt_numa_init(void);