Mailing List Archive

[xen master] xen/x86: use arch_get_ram_range to get information from E820 map
commit cfee463c112b8ac261f6ca1d32e4c70e4821ba7a
Author: Wei Chen <wei.chen@arm.com>
AuthorDate: Mon Dec 12 12:14:13 2022 +0100
Commit: Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 12 12:14:13 2022 +0100

xen/x86: use arch_get_ram_range to get information from E820 map

The sanity check of nodes_cover_memory is also a requirement of
other architectures that support NUMA. But now, the code of
nodes_cover_memory is tied to the x86 E820. In this case, we
introduce arch_get_ram_range to decouple architecture specific
memory map from this function. This means, other architectures
like Arm can also use it to check its node and memory coverage
from bootmem info.

Depends arch_get_ram_range, we make nodes_cover_memory become
architecture independent. We also use neutral words to replace
SRAT and E820 in the print message of this function. This will
to make the massage seems more common.

As arch_get_ram_range use unsigned int for index, we also adjust
the index in nodes_cover_memory from int to unsigned int.

Signed-off-by: Wei Chen <wei.chen@arm.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
xen/arch/x86/numa.c | 15 +++++++++++++++
xen/arch/x86/srat.c | 30 ++++++++++++++++++------------
xen/include/xen/numa.h | 13 +++++++++++++
3 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/xen/arch/x86/numa.c b/xen/arch/x86/numa.c
index 90b2a22591..fa8caaa084 100644
--- a/xen/arch/x86/numa.c
+++ b/xen/arch/x86/numa.c
@@ -9,6 +9,7 @@
#include <xen/nodemask.h>
#include <xen/numa.h>
#include <asm/acpi.h>
+#include <asm/e820.h>

#ifndef Dprintk
#define Dprintk(x...)
@@ -93,3 +94,17 @@ unsigned int __init arch_get_dma_bitsize(void)
flsl(node_start_pfn(node) + node_spanned_pages(node) / 4 - 1)
+ PAGE_SHIFT, 32);
}
+
+int __init arch_get_ram_range(unsigned int idx, paddr_t *start, paddr_t *end)
+{
+ if ( idx >= e820.nr_map )
+ return -ENOENT;
+
+ if ( e820.map[idx].type != E820_RAM )
+ return -ENODATA;
+
+ *start = e820.map[idx].addr;
+ *end = *start + e820.map[idx].size;
+
+ return 0;
+}
diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c
index ce507dac9e..1a108a34c6 100644
--- a/xen/arch/x86/srat.c
+++ b/xen/arch/x86/srat.c
@@ -452,37 +452,43 @@ acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity *ma)
Make sure the PXMs cover all memory. */
static int __init nodes_cover_memory(void)
{
- int i;
+ unsigned int i;

- for (i = 0; i < e820.nr_map; i++) {
- int j, found;
+ for (i = 0; ; i++) {
+ int err;
+ unsigned int j;
+ bool found;
paddr_t start, end;

- if (e820.map[i].type != E820_RAM) {
- continue;
- }
+ /* Try to loop memory map from index 0 to end to get RAM ranges. */
+ err = arch_get_ram_range(i, &start, &end);

- start = e820.map[i].addr;
- end = e820.map[i].addr + e820.map[i].size;
+ /* Reached the end of the memory map? */
+ if (err == -ENOENT)
+ break;
+
+ /* Skip non-RAM entries. */
+ if (err)
+ continue;

do {
- found = 0;
+ found = false;
for_each_node_mask(j, memory_nodes_parsed)
if (start < nodes[j].end
&& end > nodes[j].start) {
if (start >= nodes[j].start) {
start = nodes[j].end;
- found = 1;
+ found = true;
}
if (end <= nodes[j].end) {
end = nodes[j].start;
- found = 1;
+ found = true;
}
}
} while (found && start < end);

if (start < end) {
- printk(KERN_ERR "SRAT: No PXM for e820 range: "
+ printk(KERN_ERR "NUMA: No NODE for RAM range: "
"[%"PRIpaddr", %"PRIpaddr"]\n", start, end - 1);
return 0;
}
diff --git a/xen/include/xen/numa.h b/xen/include/xen/numa.h
index 04556f3a6f..9da0e7d555 100644
--- a/xen/include/xen/numa.h
+++ b/xen/include/xen/numa.h
@@ -80,6 +80,19 @@ static inline nodeid_t __attribute_pure__ phys_to_nid(paddr_t addr)
#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \
NODE_DATA(nid)->node_spanned_pages)

+/*
+ * This function provides the ability for caller to get one RAM entry
+ * from architectural memory map by index.
+ *
+ * This function will return zero if it can return a proper RAM entry.
+ * Otherwise it will return -ENOENT for out of scope index, or other
+ * error codes, e.g. return -ENODATA for non-RAM type memory entry.
+ *
+ * Note: the range is exclusive at the end, e.g. [*start, *end).
+ */
+extern int arch_get_ram_range(unsigned int idx,
+ paddr_t *start, paddr_t *end);
+
#endif

#endif /* _XEN_NUMA_H */
--
generated by git-patchbot for /home/xen/git/xen.git#master