162306a36Sopenharmony_ci==================
262306a36Sopenharmony_ciMemblock simulator
362306a36Sopenharmony_ci==================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciIntroduction
662306a36Sopenharmony_ci============
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciMemblock is a boot time memory allocator[1] that manages memory regions before
962306a36Sopenharmony_cithe actual memory management is initialized. Its APIs allow to register physical
1062306a36Sopenharmony_cimemory regions, mark them as available or reserved, allocate a block of memory
1162306a36Sopenharmony_ciwithin the requested range and/or in specific NUMA node, and many more.
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ciBecause it is used so early in the booting process, testing and debugging it is
1462306a36Sopenharmony_cidifficult. This test suite, usually referred as memblock simulator, is
1562306a36Sopenharmony_cian attempt at testing the memblock mechanism. It runs one monolithic test that
1662306a36Sopenharmony_ciconsist of a series of checks that exercise both the basic operations and
1762306a36Sopenharmony_ciallocation functionalities of memblock. The main data structure of the boot time
1862306a36Sopenharmony_cimemory allocator is initialized at the build time, so the checks here reuse its
1962306a36Sopenharmony_ciinstance throughout the duration of the test. To ensure that tests don't affect
2062306a36Sopenharmony_cieach other, region arrays are reset in between.
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciAs this project uses the actual memblock code and has to run in user space,
2362306a36Sopenharmony_cisome of the kernel definitions were stubbed by the initial commit that
2462306a36Sopenharmony_ciintroduced memblock simulator (commit 16802e55dea9 ("memblock tests: Add
2562306a36Sopenharmony_ciskeleton of the memblock simulator")) and a few preparation commits just
2662306a36Sopenharmony_cibefore it. Most of them don't match the kernel implementation, so one should
2762306a36Sopenharmony_ciconsult them first before making any significant changes to the project.
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciUsage
3062306a36Sopenharmony_ci=====
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciTo run the tests, build the main target and run it:
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci$ make && ./main
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ciA successful run produces no output. It is possible to control the behavior
3762306a36Sopenharmony_ciby passing options from command line. For example, to include verbose output,
3862306a36Sopenharmony_ciappend the `-v` options when you run the tests:
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci$ ./main -v
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ciThis will print information about which functions are being tested and the
4362306a36Sopenharmony_cinumber of test cases that passed.
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ciFor the full list of options from command line, see `./main --help`.
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ciIt is also possible to override different configuration parameters to change
4862306a36Sopenharmony_cithe test functions. For example, to simulate enabled NUMA, use:
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci$ make NUMA=1
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ciFor the full list of build options, see `make help`.
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ciProject structure
5562306a36Sopenharmony_ci=================
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ciThe project has one target, main, which calls a group of checks for basic and
5862306a36Sopenharmony_ciallocation functions. Tests for each group are defined in dedicated files, as it
5962306a36Sopenharmony_cican be seen here:
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cimemblock
6262306a36Sopenharmony_ci|-- asm       ------------------,
6362306a36Sopenharmony_ci|-- lib                         |-- implement function and struct stubs
6462306a36Sopenharmony_ci|-- linux     ------------------'
6562306a36Sopenharmony_ci|-- scripts
6662306a36Sopenharmony_ci|    |-- Makefile.include        -- handles `make` parameters
6762306a36Sopenharmony_ci|-- tests
6862306a36Sopenharmony_ci|    |-- alloc_api.(c|h)         -- memblock_alloc tests
6962306a36Sopenharmony_ci|    |-- alloc_helpers_api.(c|h) -- memblock_alloc_from tests
7062306a36Sopenharmony_ci|    |-- alloc_nid_api.(c|h)     -- memblock_alloc_try_nid tests
7162306a36Sopenharmony_ci|    |-- basic_api.(c|h)         -- memblock_add/memblock_reserve/... tests
7262306a36Sopenharmony_ci|    |-- common.(c|h)            -- helper functions for resetting memblock;
7362306a36Sopenharmony_ci|-- main.c        --------------.   dummy physical memory definition
7462306a36Sopenharmony_ci|-- Makefile                     `- test runner
7562306a36Sopenharmony_ci|-- README
7662306a36Sopenharmony_ci|-- TODO
7762306a36Sopenharmony_ci|-- .gitignore
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ciSimulating physical memory
8062306a36Sopenharmony_ci==========================
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ciSome allocation functions clear the memory in the process, so it is required for
8362306a36Sopenharmony_cimemblock to track valid memory ranges. To achieve this, the test suite registers
8462306a36Sopenharmony_ciwith memblock memory stored by test_memory struct. It is a small wrapper that
8562306a36Sopenharmony_cipoints to a block of memory allocated via malloc. For each group of allocation
8662306a36Sopenharmony_citests, dummy physical memory is allocated, added to memblock, and then released
8762306a36Sopenharmony_ciat the end of the test run. The structure of a test runner checking allocation
8862306a36Sopenharmony_cifunctions is as follows:
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ciint memblock_alloc_foo_checks(void)
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	reset_memblock_attributes();     /* data structure reset */
9362306a36Sopenharmony_ci	dummy_physical_memory_init();    /* allocate and register memory */
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	(...allocation checks...)
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	dummy_physical_memory_cleanup(); /* free the memory */
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ciThere's no need to explicitly free the dummy memory from memblock via
10162306a36Sopenharmony_cimemblock_free() call. The entry will be erased by reset_memblock_regions(),
10262306a36Sopenharmony_cicalled at the beginning of each test.
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ciKnown issues
10562306a36Sopenharmony_ci============
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci1. Requesting a specific NUMA node via memblock_alloc_node() does not work as
10862306a36Sopenharmony_ci   intended. Once the fix is in place, tests for this function can be added.
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci2. Tests for memblock_alloc_low() can't be easily implemented. The function uses
11162306a36Sopenharmony_ci   ARCH_LOW_ADDRESS_LIMIT marco, which can't be changed to point at the low
11262306a36Sopenharmony_ci   memory of the memory_block.
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ciReferences
11562306a36Sopenharmony_ci==========
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci1. Boot time memory management documentation page:
11862306a36Sopenharmony_ci   https://www.kernel.org/doc/html/latest/core-api/boot-time-mm.html
119