Back to home page

OSCL-LXR

 
 

    


0001 ==================
0002 Memblock simulator
0003 ==================
0004 
0005 Introduction
0006 ============
0007 
0008 Memblock is a boot time memory allocator[1] that manages memory regions before
0009 the actual memory management is initialized. Its APIs allow to register physical
0010 memory regions, mark them as available or reserved, allocate a block of memory
0011 within the requested range and/or in specific NUMA node, and many more.
0012 
0013 Because it is used so early in the booting process, testing and debugging it is
0014 difficult. This test suite, usually referred as memblock simulator, is
0015 an attempt at testing the memblock mechanism. It runs one monolithic test that
0016 consist of a series of checks that exercise both the basic operations and
0017 allocation functionalities of memblock. The main data structure of the boot time
0018 memory allocator is initialized at the build time, so the checks here reuse its
0019 instance throughout the duration of the test. To ensure that tests don't affect
0020 each other, region arrays are reset in between.
0021 
0022 As this project uses the actual memblock code and has to run in user space,
0023 some of the kernel definitions were stubbed by the initial commit that
0024 introduced memblock simulator (commit 16802e55dea9 ("memblock tests: Add
0025 skeleton of the memblock simulator")) and a few preparation commits just
0026 before it. Most of them don't match the kernel implementation, so one should
0027 consult them first before making any significant changes to the project.
0028 
0029 Usage
0030 =====
0031 
0032 To run the tests, build the main target and run it:
0033 
0034 $ make && ./main
0035 
0036 A successful run produces no output. It is possible to control the behavior
0037 by passing options from command line. For example, to include verbose output,
0038 append the `-v` options when you run the tests:
0039 
0040 $ ./main -v
0041 
0042 This will print information about which functions are being tested and the
0043 number of test cases that passed.
0044 
0045 For the full list of options from command line, see `./main --help`.
0046 
0047 It is also possible to override different configuration parameters to change
0048 the test functions. For example, to simulate enabled NUMA, use:
0049 
0050 $ make NUMA=1
0051 
0052 For the full list of build options, see `make help`.
0053 
0054 Project structure
0055 =================
0056 
0057 The project has one target, main, which calls a group of checks for basic and
0058 allocation functions. Tests for each group are defined in dedicated files, as it
0059 can be seen here:
0060 
0061 memblock
0062 |-- asm       ------------------,
0063 |-- lib                         |-- implement function and struct stubs
0064 |-- linux     ------------------'
0065 |-- scripts
0066 |    |-- Makefile.include        -- handles `make` parameters
0067 |-- tests
0068 |    |-- alloc_api.(c|h)         -- memblock_alloc tests
0069 |    |-- alloc_helpers_api.(c|h) -- memblock_alloc_from tests
0070 |    |-- alloc_nid_api.(c|h)     -- memblock_alloc_try_nid tests
0071 |    |-- basic_api.(c|h)         -- memblock_add/memblock_reserve/... tests
0072 |    |-- common.(c|h)            -- helper functions for resetting memblock;
0073 |-- main.c        --------------.   dummy physical memory definition
0074 |-- Makefile                     `- test runner
0075 |-- README
0076 |-- TODO
0077 |-- .gitignore
0078 
0079 Simulating physical memory
0080 ==========================
0081 
0082 Some allocation functions clear the memory in the process, so it is required for
0083 memblock to track valid memory ranges. To achieve this, the test suite registers
0084 with memblock memory stored by test_memory struct. It is a small wrapper that
0085 points to a block of memory allocated via malloc. For each group of allocation
0086 tests, dummy physical memory is allocated, added to memblock, and then released
0087 at the end of the test run. The structure of a test runner checking allocation
0088 functions is as follows:
0089 
0090 int memblock_alloc_foo_checks(void)
0091 {
0092         reset_memblock_attributes();     /* data structure reset */
0093         dummy_physical_memory_init();    /* allocate and register memory */
0094 
0095         (...allocation checks...)
0096 
0097         dummy_physical_memory_cleanup(); /* free the memory */
0098 }
0099 
0100 There's no need to explicitly free the dummy memory from memblock via
0101 memblock_free() call. The entry will be erased by reset_memblock_regions(),
0102 called at the beginning of each test.
0103 
0104 Known issues
0105 ============
0106 
0107 1. Requesting a specific NUMA node via memblock_alloc_node() does not work as
0108    intended. Once the fix is in place, tests for this function can be added.
0109 
0110 2. Tests for memblock_alloc_low() can't be easily implemented. The function uses
0111    ARCH_LOW_ADDRESS_LIMIT marco, which can't be changed to point at the low
0112    memory of the memory_block.
0113 
0114 References
0115 ==========
0116 
0117 1. Boot time memory management documentation page:
0118    https://www.kernel.org/doc/html/latest/core-api/boot-time-mm.html