xref: /linux/tools/testing/memblock/README (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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