linux/tools/testing/memblock
Linus Torvalds b8dcef877a memblock updates for v5.20
* An optimization in memblock_add_range() to reduce array traversals
 * Improvements to the memblock test suite
 -----BEGIN PGP SIGNATURE-----
 
 iQFMBAABCAA2FiEEeOVYVaWZL5900a/pOQOGJssO/ZEFAmLyCbgYHG1pa2UucmFw
 b3BvcnRAZ21haWwuY29tAAoJEDkDhibLDv2RBxMH/1uIcfERl3Cbw25zluWSVn4O
 mrnr+JPqUkyeVLQDEGzk/VWIM1WT11s7fFpoTpIwu3dq/fVoD3HZlZQkWS0ANFDL
 V3xf6Xz17R5ZNoZmacczhNaBqkJSi+dcvoAevjyBHPpKEaCLC/rNrISpDdCD0Lz0
 5fgv2F4sISBUVc6FVIFB+9zKC/neI9ewemCABSFTIa5mmQvZZwX1Tj5BrxIsESwN
 DwX5u1Q65SoFBbAk6F5+aoClJ7wMGz8OlZoFw106HTvxq8sNne27KXW9mKugBzJr
 yAZ/TWrjXigNAr8dcXQEZuxagFSB1PQ4aNgU8phiAwE7/5z3j1KLa65hDRzc9t4=
 =JMiG
 -----END PGP SIGNATURE-----

Merge tag 'memblock-v5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock

Pull memblock updates from Mike Rapoport:

 - An optimization in memblock_add_range() to reduce array traversals

 - Improvements to the memblock test suite

* tag 'memblock-v5.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock:
  memblock test: Modify the obsolete description in README
  memblock tests: fix compilation errors
  memblock tests: change build options to run-time options
  memblock tests: remove completed TODO items
  memblock tests: set memblock_debug to enable memblock_dbg() messages
  memblock tests: add verbose output to memblock tests
  memblock tests: Makefile: add arguments to control verbosity
  memblock: avoid some repeat when add new range
2022-08-09 09:48:30 -07:00
..
asm
lib
linux memblock updates for v5.20 2022-08-09 09:48:30 -07:00
scripts memblock tests: change build options to run-time options 2022-07-20 10:46:33 +03:00
tests memblock tests: change build options to run-time options 2022-07-20 10:46:33 +03:00
.gitignore
internal.h memblock tests: fix compilation errors 2022-07-29 09:34:50 +03:00
main.c memblock tests: change build options to run-time options 2022-07-20 10:46:33 +03:00
Makefile memblock tests: change build options to run-time options 2022-07-20 10:46:33 +03:00
mmzone.c
README memblock test: Modify the obsolete description in README 2022-07-30 11:46:49 +03:00
TODO memblock tests: remove completed TODO items 2022-07-04 19:58:28 +03:00

==================
Memblock simulator
==================

Introduction
============

Memblock is a boot time memory allocator[1] that manages memory regions before
the actual memory management is initialized. Its APIs allow to register physical
memory regions, mark them as available or reserved, allocate a block of memory
within the requested range and/or in specific NUMA node, and many more.

Because it is used so early in the booting process, testing and debugging it is
difficult. This test suite, usually referred as memblock simulator, is
an attempt at testing the memblock mechanism. It runs one monolithic test that
consist of a series of checks that exercise both the basic operations and
allocation functionalities of memblock. The main data structure of the boot time
memory allocator is initialized at the build time, so the checks here reuse its
instance throughout the duration of the test. To ensure that tests don't affect
each other, region arrays are reset in between.

As this project uses the actual memblock code and has to run in user space,
some of the kernel definitions were stubbed by the initial commit that
introduced memblock simulator (commit 16802e55dea9 ("memblock tests: Add
skeleton of the memblock simulator")) and a few preparation commits just
before it. Most of them don't match the kernel implementation, so one should
consult them first before making any significant changes to the project.

Usage
=====

To run the tests, build the main target and run it:

$ make && ./main

A successful run produces no output. It is possible to control the behavior
by passing options from command line. For example, to include verbose output,
append the `-v` options when you run the tests:

$ ./main -v

This will print information about which functions are being tested and the
number of test cases that passed.

For the full list of options from command line, see `./main --help`.

It is also possible to override different configuration parameters to change
the test functions. For example, to simulate enabled NUMA, use:

$ make NUMA=1

For the full list of build options, see `make help`.

Project structure
=================

The project has one target, main, which calls a group of checks for basic and
allocation functions. Tests for each group are defined in dedicated files, as it
can be seen here:

memblock
|-- asm       ------------------,
|-- lib                         |-- implement function and struct stubs
|-- linux     ------------------'
|-- scripts
|    |-- Makefile.include        -- handles `make` parameters
|-- tests
|    |-- alloc_api.(c|h)         -- memblock_alloc tests
|    |-- alloc_helpers_api.(c|h) -- memblock_alloc_from tests
|    |-- alloc_nid_api.(c|h)     -- memblock_alloc_try_nid tests
|    |-- basic_api.(c|h)         -- memblock_add/memblock_reserve/... tests
|    |-- common.(c|h)            -- helper functions for resetting memblock;
|-- main.c        --------------.   dummy physical memory definition
|-- Makefile                     `- test runner
|-- README
|-- TODO
|-- .gitignore

Simulating physical memory
==========================

Some allocation functions clear the memory in the process, so it is required for
memblock to track valid memory ranges. To achieve this, the test suite registers
with memblock memory stored by test_memory struct. It is a small wrapper that
points to a block of memory allocated via malloc. For each group of allocation
tests, dummy physical memory is allocated, added to memblock, and then released
at the end of the test run. The structure of a test runner checking allocation
functions is as follows:

int memblock_alloc_foo_checks(void)
{
	reset_memblock_attributes();     /* data structure reset */
	dummy_physical_memory_init();    /* allocate and register memory */

	(...allocation checks...)

	dummy_physical_memory_cleanup(); /* free the memory */
}

There's no need to explicitly free the dummy memory from memblock via
memblock_free() call. The entry will be erased by reset_memblock_regions(),
called at the beginning of each test.

Known issues
============

1. Requesting a specific NUMA node via memblock_alloc_node() does not work as
   intended. Once the fix is in place, tests for this function can be added.

2. Tests for memblock_alloc_low() can't be easily implemented. The function uses
   ARCH_LOW_ADDRESS_LIMIT marco, which can't be changed to point at the low
   memory of the memory_block.

References
==========

1. Boot time memory management documentation page:
   https://www.kernel.org/doc/html/latest/core-api/boot-time-mm.html