@@ -3,7 +3,7 @@
# Simulate CONFIG_NUMA=y
ifeq ($(NUMA), 1)
- CFLAGS += -D CONFIG_NUMA
+ CFLAGS += -D CONFIG_NUMA -D CONFIG_NODES_SHIFT=4
endif
# Use 32 bit physical addresses.
@@ -34,6 +34,10 @@ static const char * const help_opts[] = {
static int verbose;
+static const phys_addr_t node_sizes[] = {
+ SZ_4K, SZ_1K, SZ_2K, SZ_2K, SZ_1K, SZ_1K, SZ_4K, SZ_1K
+};
+
/* sets global variable returned by movable_node_is_enabled() stub */
bool movable_node_enabled;
@@ -72,6 +76,40 @@ void setup_memblock(void)
fill_memblock();
}
+/**
+ * setup_numa_memblock_generic:
+ * Set up a memory layout with multiple NUMA nodes in a previously allocated
+ * dummy physical memory.
+ * @nodes: an array containing the amount of memory in each node
+ * @node_cnt: the size of @nodes
+ * @factor: a factor that will be used to scale the memory in each node
+ *
+ * The nids will be set to 0 through node_cnt - 1.
+ */
+void setup_numa_memblock_generic(const phys_addr_t nodes[],
+ int node_cnt, int factor)
+{
+ phys_addr_t base;
+ int flags;
+
+ reset_memblock_regions();
+ base = (phys_addr_t)memory_block.base;
+ flags = (movable_node_is_enabled()) ? MEMBLOCK_NONE : MEMBLOCK_HOTPLUG;
+
+ for (int i = 0; i < node_cnt; i++) {
+ phys_addr_t size = factor * nodes[i];
+
+ memblock_add_node(base, size, i, flags);
+ base += size;
+ }
+ fill_memblock();
+}
+
+void setup_numa_memblock(void)
+{
+ setup_numa_memblock_generic(node_sizes, NUMA_NODES, MEM_FACTOR);
+}
+
void dummy_physical_memory_init(void)
{
memory_block.base = malloc(MEM_SIZE);
@@ -10,7 +10,11 @@
#include <linux/printk.h>
#include <../selftests/kselftest.h>
-#define MEM_SIZE SZ_16K
+#define MEM_SIZE SZ_16K
+#define NUMA_NODES 8
+
+/* used to resize values that need to scale with MEM_SIZE */
+#define MEM_FACTOR (MEM_SIZE / SZ_16K)
enum test_flags {
/* No special request. */
@@ -102,6 +106,9 @@ struct region {
void reset_memblock_regions(void);
void reset_memblock_attributes(void);
void setup_memblock(void);
+void setup_numa_memblock_generic(const phys_addr_t nodes[],
+ int node_cnt, int factor);
+void setup_numa_memblock(void);
void dummy_physical_memory_init(void);
void dummy_physical_memory_cleanup(void);
void parse_args(int argc, char **argv);
Add functions setup_numa_memblock_generic() and setup_numa_memblock() for setting up a memory layout with multiple NUMA nodes in a previously allocated dummy physical memory. These functions can be used in place of setup_memblock() in tests that need to simulate a NUMA system. setup_numa_memblock_generic(): - allows for setting up a custom memory layout by specifying the amount of memory in each node, the number of nodes, and a factor that will be used to scale the memory in each node setup_numa_memblock(): - allows for setting up a default memory layout Introduce constant MEM_FACTOR, which is used to scale the default memory layout based on MEM_SIZE. Set CONFIG_NODES_SHIFT to 4 when building with NUMA=1 to allow for up to 16 NUMA nodes. Signed-off-by: Rebecca Mckeever <remckee0@gmail.com> --- .../testing/memblock/scripts/Makefile.include | 2 +- tools/testing/memblock/tests/common.c | 38 +++++++++++++++++++ tools/testing/memblock/tests/common.h | 9 ++++- 3 files changed, 47 insertions(+), 2 deletions(-)