158ffc348SKarolina Drobnik================== 258ffc348SKarolina DrobnikMemblock simulator 358ffc348SKarolina Drobnik================== 458ffc348SKarolina Drobnik 558ffc348SKarolina DrobnikIntroduction 658ffc348SKarolina Drobnik============ 758ffc348SKarolina Drobnik 858ffc348SKarolina DrobnikMemblock is a boot time memory allocator[1] that manages memory regions before 958ffc348SKarolina Drobnikthe actual memory management is initialized. Its APIs allow to register physical 1058ffc348SKarolina Drobnikmemory regions, mark them as available or reserved, allocate a block of memory 1158ffc348SKarolina Drobnikwithin the requested range and/or in specific NUMA node, and many more. 1258ffc348SKarolina Drobnik 1358ffc348SKarolina DrobnikBecause it is used so early in the booting process, testing and debugging it is 1458ffc348SKarolina Drobnikdifficult. This test suite, usually referred as memblock simulator, is 1558ffc348SKarolina Drobnikan attempt at testing the memblock mechanism. It runs one monolithic test that 1658ffc348SKarolina Drobnikconsist of a series of checks that exercise both the basic operations and 1758ffc348SKarolina Drobnikallocation functionalities of memblock. The main data structure of the boot time 1858ffc348SKarolina Drobnikmemory allocator is initialized at the build time, so the checks here reuse its 1958ffc348SKarolina Drobnikinstance throughout the duration of the test. To ensure that tests don't affect 2058ffc348SKarolina Drobnikeach other, region arrays are reset in between. 2158ffc348SKarolina Drobnik 2258ffc348SKarolina DrobnikAs this project uses the actual memblock code and has to run in user space, 2358ffc348SKarolina Drobniksome of the kernel definitions were stubbed by the initial commit that 2458ffc348SKarolina Drobnikintroduced memblock simulator (commit 16802e55dea9 ("memblock tests: Add 2558ffc348SKarolina Drobnikskeleton of the memblock simulator")) and a few preparation commits just 2658ffc348SKarolina Drobnikbefore it. Most of them don't match the kernel implementation, so one should 2758ffc348SKarolina Drobnikconsult them first before making any significant changes to the project. 2858ffc348SKarolina Drobnik 2958ffc348SKarolina DrobnikUsage 3058ffc348SKarolina Drobnik===== 3158ffc348SKarolina Drobnik 3258ffc348SKarolina DrobnikTo run the tests, build the main target and run it: 3358ffc348SKarolina Drobnik 3458ffc348SKarolina Drobnik$ make && ./main 3558ffc348SKarolina Drobnik 36*04d94909SShaoqin HuangA successful run produces no output. It is possible to control the behavior 37*04d94909SShaoqin Huangby passing options from command line. For example, to include verbose output, 38*04d94909SShaoqin Huangappend the `-v` options when you run the tests: 39946dccb3SRebecca Mckeever 40*04d94909SShaoqin Huang$ ./main -v 41946dccb3SRebecca Mckeever 42946dccb3SRebecca MckeeverThis will print information about which functions are being tested and the 43946dccb3SRebecca Mckeevernumber of test cases that passed. 44946dccb3SRebecca Mckeever 45*04d94909SShaoqin HuangFor the full list of options from command line, see `./main --help`. 46*04d94909SShaoqin Huang 47*04d94909SShaoqin HuangIt is also possible to override different configuration parameters to change 48*04d94909SShaoqin Huangthe test functions. For example, to simulate enabled NUMA, use: 4958ffc348SKarolina Drobnik 5058ffc348SKarolina Drobnik$ make NUMA=1 5158ffc348SKarolina Drobnik 52*04d94909SShaoqin HuangFor the full list of build options, see `make help`. 5358ffc348SKarolina Drobnik 5458ffc348SKarolina DrobnikProject structure 5558ffc348SKarolina Drobnik================= 5658ffc348SKarolina Drobnik 5758ffc348SKarolina DrobnikThe project has one target, main, which calls a group of checks for basic and 5858ffc348SKarolina Drobnikallocation functions. Tests for each group are defined in dedicated files, as it 5958ffc348SKarolina Drobnikcan be seen here: 6058ffc348SKarolina Drobnik 6158ffc348SKarolina Drobnikmemblock 6258ffc348SKarolina Drobnik|-- asm ------------------, 6358ffc348SKarolina Drobnik|-- lib |-- implement function and struct stubs 6458ffc348SKarolina Drobnik|-- linux ------------------' 6558ffc348SKarolina Drobnik|-- scripts 6658ffc348SKarolina Drobnik| |-- Makefile.include -- handles `make` parameters 6758ffc348SKarolina Drobnik|-- tests 6858ffc348SKarolina Drobnik| |-- alloc_api.(c|h) -- memblock_alloc tests 6958ffc348SKarolina Drobnik| |-- alloc_helpers_api.(c|h) -- memblock_alloc_from tests 7058ffc348SKarolina Drobnik| |-- alloc_nid_api.(c|h) -- memblock_alloc_try_nid tests 7158ffc348SKarolina Drobnik| |-- basic_api.(c|h) -- memblock_add/memblock_reserve/... tests 7258ffc348SKarolina Drobnik| |-- common.(c|h) -- helper functions for resetting memblock; 7358ffc348SKarolina Drobnik|-- main.c --------------. dummy physical memory definition 7458ffc348SKarolina Drobnik|-- Makefile `- test runner 7558ffc348SKarolina Drobnik|-- README 7658ffc348SKarolina Drobnik|-- TODO 7758ffc348SKarolina Drobnik|-- .gitignore 7858ffc348SKarolina Drobnik 7958ffc348SKarolina DrobnikSimulating physical memory 8058ffc348SKarolina Drobnik========================== 8158ffc348SKarolina Drobnik 8258ffc348SKarolina DrobnikSome allocation functions clear the memory in the process, so it is required for 8358ffc348SKarolina Drobnikmemblock to track valid memory ranges. To achieve this, the test suite registers 8458ffc348SKarolina Drobnikwith memblock memory stored by test_memory struct. It is a small wrapper that 8558ffc348SKarolina Drobnikpoints to a block of memory allocated via malloc. For each group of allocation 8658ffc348SKarolina Drobniktests, dummy physical memory is allocated, added to memblock, and then released 8758ffc348SKarolina Drobnikat the end of the test run. The structure of a test runner checking allocation 8858ffc348SKarolina Drobnikfunctions is as follows: 8958ffc348SKarolina Drobnik 9058ffc348SKarolina Drobnikint memblock_alloc_foo_checks(void) 9158ffc348SKarolina Drobnik{ 9258ffc348SKarolina Drobnik reset_memblock_attributes(); /* data structure reset */ 9358ffc348SKarolina Drobnik dummy_physical_memory_init(); /* allocate and register memory */ 9458ffc348SKarolina Drobnik 9558ffc348SKarolina Drobnik (...allocation checks...) 9658ffc348SKarolina Drobnik 9758ffc348SKarolina Drobnik dummy_physical_memory_cleanup(); /* free the memory */ 9858ffc348SKarolina Drobnik} 9958ffc348SKarolina Drobnik 10058ffc348SKarolina DrobnikThere's no need to explicitly free the dummy memory from memblock via 10158ffc348SKarolina Drobnikmemblock_free() call. The entry will be erased by reset_memblock_regions(), 10258ffc348SKarolina Drobnikcalled at the beginning of each test. 10358ffc348SKarolina Drobnik 10458ffc348SKarolina DrobnikKnown issues 10558ffc348SKarolina Drobnik============ 10658ffc348SKarolina Drobnik 10758ffc348SKarolina Drobnik1. Requesting a specific NUMA node via memblock_alloc_node() does not work as 10858ffc348SKarolina Drobnik intended. Once the fix is in place, tests for this function can be added. 10958ffc348SKarolina Drobnik 11058ffc348SKarolina Drobnik2. Tests for memblock_alloc_low() can't be easily implemented. The function uses 11158ffc348SKarolina Drobnik ARCH_LOW_ADDRESS_LIMIT marco, which can't be changed to point at the low 11258ffc348SKarolina Drobnik memory of the memory_block. 11358ffc348SKarolina Drobnik 11458ffc348SKarolina DrobnikReferences 11558ffc348SKarolina Drobnik========== 11658ffc348SKarolina Drobnik 11758ffc348SKarolina Drobnik1. Boot time memory management documentation page: 11858ffc348SKarolina Drobnik https://www.kernel.org/doc/html/latest/core-api/boot-time-mm.html 119