Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

memblock tests: add simulation of physical memory with multiple NUMA nodes

Add function setup_numa_memblock() for setting up a memory layout with
multiple NUMA nodes in a previously allocated dummy physical memory.
This function can be used in place of setup_memblock() in tests that need
to simulate a NUMA system.

setup_numa_memblock():
- allows for setting up a memory layout by specifying the fraction of
MEM_SIZE in each node

Set CONFIG_NODES_SHIFT to 4 when building with NUMA=1 to allow for up to
16 NUMA nodes.

Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Rebecca Mckeever <remckee0@gmail.com>
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Link: https://lore.kernel.org/r/4566d816a85f009268d4858d1ef06c7571a960f9.1663046060.git.remckee0@gmail.com

authored by

Rebecca Mckeever and committed by
Mike Rapoport
b338bde5 42c3ba86

+35 -2
+1 -1
tools/testing/memblock/scripts/Makefile.include
··· 3 3 4 4 # Simulate CONFIG_NUMA=y 5 5 ifeq ($(NUMA), 1) 6 - CFLAGS += -D CONFIG_NUMA 6 + CFLAGS += -D CONFIG_NUMA -D CONFIG_NODES_SHIFT=4 7 7 endif 8 8 9 9 # Use 32 bit physical addresses.
+31
tools/testing/memblock/tests/common.c
··· 9 9 #define INIT_MEMBLOCK_RESERVED_REGIONS INIT_MEMBLOCK_REGIONS 10 10 #define PREFIXES_MAX 15 11 11 #define DELIM ": " 12 + #define BASIS 10000 12 13 13 14 static struct test_memory memory_block; 14 15 static const char __maybe_unused *prefixes[PREFIXES_MAX]; ··· 70 69 { 71 70 reset_memblock_regions(); 72 71 memblock_add((phys_addr_t)memory_block.base, MEM_SIZE); 72 + fill_memblock(); 73 + } 74 + 75 + /** 76 + * setup_numa_memblock: 77 + * Set up a memory layout with multiple NUMA nodes in a previously allocated 78 + * dummy physical memory. 79 + * @node_fracs: an array representing the fraction of MEM_SIZE contained in 80 + * each node in basis point units (one hundredth of 1% or 1/10000). 81 + * For example, if node 0 should contain 1/8 of MEM_SIZE, 82 + * node_fracs[0] = 1250. 83 + * 84 + * The nids will be set to 0 through NUMA_NODES - 1. 85 + */ 86 + void setup_numa_memblock(const unsigned int node_fracs[]) 87 + { 88 + phys_addr_t base; 89 + int flags; 90 + 91 + reset_memblock_regions(); 92 + base = (phys_addr_t)memory_block.base; 93 + flags = (movable_node_is_enabled()) ? MEMBLOCK_NONE : MEMBLOCK_HOTPLUG; 94 + 95 + for (int i = 0; i < NUMA_NODES; i++) { 96 + assert(node_fracs[i] <= BASIS); 97 + phys_addr_t size = MEM_SIZE * node_fracs[i] / BASIS; 98 + 99 + memblock_add_node(base, size, i, flags); 100 + base += size; 101 + } 73 102 fill_memblock(); 74 103 } 75 104
+3 -1
tools/testing/memblock/tests/common.h
··· 10 10 #include <linux/printk.h> 11 11 #include <../selftests/kselftest.h> 12 12 13 - #define MEM_SIZE SZ_16K 13 + #define MEM_SIZE SZ_16K 14 + #define NUMA_NODES 8 14 15 15 16 enum test_flags { 16 17 /* No special request. */ ··· 103 102 void reset_memblock_regions(void); 104 103 void reset_memblock_attributes(void); 105 104 void setup_memblock(void); 105 + void setup_numa_memblock(const unsigned int node_fracs[]); 106 106 void dummy_physical_memory_init(void); 107 107 void dummy_physical_memory_cleanup(void); 108 108 void parse_args(int argc, char **argv);