1================== 2Memblock simulator 3================== 4 5Introduction 6============ 7 8Memblock is a boot time memory allocator[1] that manages memory regions before 9the actual memory management is initialized. Its APIs allow to register physical 10memory regions, mark them as available or reserved, allocate a block of memory 11within the requested range and/or in specific NUMA node, and many more. 12 13Because it is used so early in the booting process, testing and debugging it is 14difficult. This test suite, usually referred as memblock simulator, is 15an attempt at testing the memblock mechanism. It runs one monolithic test that 16consist of a series of checks that exercise both the basic operations and 17allocation functionalities of memblock. The main data structure of the boot time 18memory allocator is initialized at the build time, so the checks here reuse its 19instance throughout the duration of the test. To ensure that tests don't affect 20each other, region arrays are reset in between. 21 22As this project uses the actual memblock code and has to run in user space, 23some of the kernel definitions were stubbed by the initial commit that 24introduced memblock simulator (commit 16802e55dea9 ("memblock tests: Add 25skeleton of the memblock simulator")) and a few preparation commits just 26before it. Most of them don't match the kernel implementation, so one should 27consult them first before making any significant changes to the project. 28 29Usage 30===== 31 32To run the tests, build the main target and run it: 33 34$ make && ./main 35 36A successful run produces no output. It is also possible to override different 37configuration parameters. For example, to include verbose output, specify the 38VERBOSE flag when building the main target: 39 40$ make VERBOSE=1 41 42This will print information about which functions are being tested and the 43number of test cases that passed. 44 45To simulate enabled NUMA, use: 46 47$ make NUMA=1 48 49For the full list of options, see `make help`. 50 51Project structure 52================= 53 54The project has one target, main, which calls a group of checks for basic and 55allocation functions. Tests for each group are defined in dedicated files, as it 56can be seen here: 57 58memblock 59|-- asm ------------------, 60|-- lib |-- implement function and struct stubs 61|-- linux ------------------' 62|-- scripts 63| |-- Makefile.include -- handles `make` parameters 64|-- tests 65| |-- alloc_api.(c|h) -- memblock_alloc tests 66| |-- alloc_helpers_api.(c|h) -- memblock_alloc_from tests 67| |-- alloc_nid_api.(c|h) -- memblock_alloc_try_nid tests 68| |-- basic_api.(c|h) -- memblock_add/memblock_reserve/... tests 69| |-- common.(c|h) -- helper functions for resetting memblock; 70|-- main.c --------------. dummy physical memory definition 71|-- Makefile `- test runner 72|-- README 73|-- TODO 74|-- .gitignore 75 76Simulating physical memory 77========================== 78 79Some allocation functions clear the memory in the process, so it is required for 80memblock to track valid memory ranges. To achieve this, the test suite registers 81with memblock memory stored by test_memory struct. It is a small wrapper that 82points to a block of memory allocated via malloc. For each group of allocation 83tests, dummy physical memory is allocated, added to memblock, and then released 84at the end of the test run. The structure of a test runner checking allocation 85functions is as follows: 86 87int memblock_alloc_foo_checks(void) 88{ 89 reset_memblock_attributes(); /* data structure reset */ 90 dummy_physical_memory_init(); /* allocate and register memory */ 91 92 (...allocation checks...) 93 94 dummy_physical_memory_cleanup(); /* free the memory */ 95} 96 97There's no need to explicitly free the dummy memory from memblock via 98memblock_free() call. The entry will be erased by reset_memblock_regions(), 99called at the beginning of each test. 100 101Known issues 102============ 103 1041. Requesting a specific NUMA node via memblock_alloc_node() does not work as 105 intended. Once the fix is in place, tests for this function can be added. 106 1072. Tests for memblock_alloc_low() can't be easily implemented. The function uses 108 ARCH_LOW_ADDRESS_LIMIT marco, which can't be changed to point at the low 109 memory of the memory_block. 110 111References 112========== 113 1141. Boot time memory management documentation page: 115 https://www.kernel.org/doc/html/latest/core-api/boot-time-mm.html 116