diff options
Diffstat (limited to 'Documentation/dev-tools')
31 files changed, 1068 insertions, 84 deletions
diff --git a/Documentation/dev-tools/autofdo.rst b/Documentation/dev-tools/autofdo.rst index 1f0a451e9ccd..bcf06e7d6ffa 100644 --- a/Documentation/dev-tools/autofdo.rst +++ b/Documentation/dev-tools/autofdo.rst @@ -131,11 +131,11 @@ Here is an example workflow for AutoFDO kernel: For Zen3:: - $ cat proc/cpuinfo | grep " brs" + $ cat /proc/cpuinfo | grep " brs" For Zen4:: - $ cat proc/cpuinfo | grep amd_lbr_v2 + $ cat /proc/cpuinfo | grep amd_lbr_v2 The following command generated the perf data file:: diff --git a/Documentation/dev-tools/checkpatch.rst b/Documentation/dev-tools/checkpatch.rst index abb3ff682076..dccede68698c 100644 --- a/Documentation/dev-tools/checkpatch.rst +++ b/Documentation/dev-tools/checkpatch.rst @@ -342,24 +342,6 @@ API usage See: https://www.kernel.org/doc/html/latest/RCU/whatisRCU.html#full-list-of-rcu-apis - **DEPRECATED_VARIABLE** - EXTRA_{A,C,CPP,LD}FLAGS are deprecated and should be replaced by the new - flags added via commit f77bf01425b1 ("kbuild: introduce ccflags-y, - asflags-y and ldflags-y"). - - The following conversion scheme maybe used:: - - EXTRA_AFLAGS -> asflags-y - EXTRA_CFLAGS -> ccflags-y - EXTRA_CPPFLAGS -> cppflags-y - EXTRA_LDFLAGS -> ldflags-y - - See: - - 1. https://lore.kernel.org/lkml/20070930191054.GA15876@uranus.ravnborg.org/ - 2. https://lore.kernel.org/lkml/1313384834-24433-12-git-send-email-lacombar@gmail.com/ - 3. https://www.kernel.org/doc/html/latest/kbuild/makefiles.html#compilation-flags - **DEVICE_ATTR_FUNCTIONS** The function names used in DEVICE_ATTR is unusual. Typically, the store and show functions are used with <attr>_store and @@ -479,16 +461,9 @@ Comments line comments is:: /* - * This is the preferred style - * for multi line comments. - */ - - The networking comment style is a bit different, with the first line - not empty like the former:: - - /* This is the preferred comment style - * for files in net/ and drivers/net/ - */ + * This is the preferred style + * for multi line comments. + */ See: https://www.kernel.org/doc/html/latest/process/coding-style.html#commenting @@ -513,6 +488,15 @@ Comments See: https://lore.kernel.org/lkml/20131006222342.GT19510@leaf/ + **UNCOMMENTED_RGMII_MODE** + Historically, the RGMII PHY modes specified in Device Trees have been + used inconsistently, often referring to the usage of delays on the PHY + side rather than describing the board. + + PHY modes "rgmii", "rgmii-rxid" and "rgmii-txid" modes require the clock + signal to be delayed on the PCB; this unusual configuration should be + described in a comment. If they are not (meaning that the delay is realized + internally in the MAC or PHY), "rgmii-id" is the correct PHY mode. Commit message -------------- @@ -617,6 +601,11 @@ Commit message See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes + **BAD_COMMIT_SEPARATOR** + The commit separator is a single line with 3 dashes. + The regex match is '^---$' + Lines that start with 3 dashes and have more content on the same line + may confuse tools that apply patches. Comparison style ---------------- @@ -769,7 +758,7 @@ Macros, Attributes and Symbols sizeof(foo)/sizeof(foo[0]) for finding number of elements in an array. - The macro is defined in include/linux/kernel.h:: + The macro is defined in include/linux/array_size.h:: #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -1018,6 +1007,29 @@ Functions and Variables return bar; + **UNINITIALIZED_PTR_WITH_FREE** + Pointers with __free attribute should be declared at the place of use + and initialized (see include/linux/cleanup.h). In this case + declarations at the top of the function rule can be relaxed. Not doing + so may lead to undefined behavior as the memory assigned (garbage, + in case not initialized) to the pointer is freed automatically when + the pointer goes out of scope. + + Also see: https://lore.kernel.org/lkml/58fd478f408a34b578ee8d949c5c4b4da4d4f41d.camel@HansenPartnership.com/ + + Example:: + + type var __free(free_func); + ... // var not used, but, in future someone might add a return here + var = malloc(var_size); + ... + + should be initialized as:: + + ... + type var __free(free_func) = malloc(var_size); + ... + Permissions ----------- @@ -1254,6 +1266,16 @@ Others The patch file does not appear to be in unified-diff format. Please regenerate the patch file before sending it to the maintainer. + **PLACEHOLDER_USE** + Detects unhandled placeholder text left in cover letters or commit headers/logs. + Common placeholders include lines like:: + + *** SUBJECT HERE *** + *** BLURB HERE *** + + These typically come from autogenerated templates. Replace them with a proper + subject and description before sending. + **PRINTF_0XDECIMAL** Prefixing 0x with decimal output is defective and should be corrected. diff --git a/Documentation/dev-tools/clang-format.rst b/Documentation/dev-tools/clang-format.rst index 1d089a847c1b..6c8a0df5a00c 100644 --- a/Documentation/dev-tools/clang-format.rst +++ b/Documentation/dev-tools/clang-format.rst @@ -88,7 +88,7 @@ Reformatting blocks of code By using an integration with your text editor, you can reformat arbitrary blocks (selections) of code with a single keystroke. This is specially -useful when moving code around, for complex code that is deeply intended, +useful when moving code around, for complex code that is deeply indented, for multi-line macros (and aligning their backslashes), etc. Remember that you can always tweak the changes afterwards in those cases diff --git a/Documentation/dev-tools/coccinelle.rst b/Documentation/dev-tools/coccinelle.rst index 6e70a1e9a3c0..b8ecb481ddff 100644 --- a/Documentation/dev-tools/coccinelle.rst +++ b/Documentation/dev-tools/coccinelle.rst @@ -29,12 +29,13 @@ of many distributions, e.g. : - Ubuntu - OpenSUSE - Arch Linux + - Gentoo - NetBSD - FreeBSD Some distribution packages are obsolete and it is recommended to use the latest version released from the Coccinelle homepage at -http://coccinelle.lip6.fr/ +https://coccinelle.gitlabpages.inria.fr/website Or from Github at: @@ -60,7 +61,7 @@ Supplemental documentation For supplemental documentation refer to the wiki: -https://bottest.wiki.kernel.org/coccicheck +https://bottest.wiki.kernel.org/coccicheck.html The wiki documentation always refers to the linux-next version of the script. @@ -127,6 +128,18 @@ To enable verbose messages set the V= variable, for example:: make coccicheck MODE=report V=1 +By default, coccicheck will print debug logs to stdout and redirect stderr to +/dev/null. This can make coccicheck output difficult to read and understand. +Debug and error messages can instead be written to a debug file instead by +setting the ``DEBUG_FILE`` variable:: + + make coccicheck MODE=report DEBUG_FILE="cocci.log" + +Coccinelle cannot overwrite a debug file. Instead of repeatedly deleting a log +file, you could include the datetime in the debug file name:: + + make coccicheck MODE=report DEBUG_FILE="cocci-$(date -Iseconds).log" + Coccinelle parallelization -------------------------- @@ -208,11 +221,10 @@ include options matching the options used when we compile the kernel. You can learn what these options are by using V=1; you could then manually run Coccinelle with debug options added. -Alternatively you can debug running Coccinelle against SmPL patches -by asking for stderr to be redirected to stderr. By default stderr -is redirected to /dev/null; if you'd like to capture stderr you -can specify the ``DEBUG_FILE="file.txt"`` option to coccicheck. For -instance:: +An easier approach to debug running Coccinelle against SmPL patches is to ask +coccicheck to redirect stderr to a debug file. As mentioned in the examples, by +default stderr is redirected to /dev/null; if you'd like to capture stderr you +can specify the ``DEBUG_FILE="file.txt"`` option to coccicheck. For instance:: rm -f cocci.err make coccicheck COCCI=scripts/coccinelle/free/kfree.cocci MODE=report DEBUG_FILE=cocci.err diff --git a/Documentation/dev-tools/container.rst b/Documentation/dev-tools/container.rst new file mode 100644 index 000000000000..452415b64662 --- /dev/null +++ b/Documentation/dev-tools/container.rst @@ -0,0 +1,227 @@ +.. SPDX-License-Identifier: GPL-2.0-only +.. Copyright (C) 2025 Guillaume Tucker + +==================== +Containerized Builds +==================== + +The ``container`` tool can be used to run any command in the kernel source tree +from within a container. Doing so facilitates reproducing builds across +various platforms, for example when a test bot has reported an issue which +requires a specific version of a compiler or an external test suite. While +this can already be done by users who are familiar with containers, having a +dedicated tool in the kernel tree lowers the barrier to entry by solving common +problems once and for all (e.g. user id management). It also makes it easier +to share an exact command line leading to a particular result. The main use +case is likely to be kernel builds but virtually anything can be run: KUnit, +checkpatch etc. provided a suitable image is available. + + +Options +======= + +Command line syntax:: + + scripts/container -i IMAGE [OPTION]... CMD... + +Available options: + +``-e, --env-file ENV_FILE`` + + Path to an environment file to load in the container. + +``-g, --gid GID`` + + Group id to use inside the container. + +``-i, --image IMAGE`` + + Container image name (required). + +``-r, --runtime RUNTIME`` + + Container runtime name. Supported runtimes: ``docker``, ``podman``. + + If not specified, the first one found on the system will be used + i.e. Podman if present, otherwise Docker. + +``-s, --shell`` + + Run the container in an interactive shell. + +``-u, --uid UID`` + + User id to use inside the container. + + If the ``-g`` option is not specified, the user id will also be used for + the group id. + +``-v, --verbose`` + + Enable verbose output. + +``-h, --help`` + + Show the help message and exit. + + +Usage +===== + +It's entirely up to the user to choose which image to use and the ``CMD`` +arguments are passed directly as an arbitrary command line to run in the +container. The tool will take care of mounting the source tree as the current +working directory and adjust the user and group id as needed. + +The container image which would typically include a compiler toolchain is +provided by the user and selected via the ``-i`` option. The container runtime +can be selected with the ``-r`` option, which can be either ``docker`` or +``podman``. If none is specified, the first one found on the system will be +used while giving priority to Podman. Support for other runtimes may be added +later depending on their popularity among users. + +By default, commands are run non-interactively. The user can abort a running +container with SIGINT (Ctrl-C). To run commands interactively with a TTY, the +``--shell`` or ``-s`` option can be used. Signals will then be received by the +shell directly rather than the parent ``container`` process. To exit an +interactive shell, use Ctrl-D or ``exit``. + +.. note:: + + The only host requirement aside from a container runtime is Python 3.10 or + later. + +.. note:: + + Out-of-tree builds are not fully supported yet. The ``O=`` option can + however already be used with a relative path inside the source tree to keep + separate build outputs. A workaround to build outside the tree is to use + ``mount --bind``, see the examples section further down. + + +Environment Variables +===================== + +Environment variables are not propagated to the container so they have to be +either defined in the image itself or via the ``-e`` option using an +environment file. In some cases it makes more sense to have them defined in +the Containerfile used to create the image. For example, a Clang-only compiler +toolchain image may have ``LLVM=1`` defined. + +The local environment file is more useful for user-specific variables added +during development. It is passed as-is to the container runtime so its format +may vary. Typically, it will look like the output of ``env``. For example:: + + INSTALL_MOD_STRIP=1 + SOME_RANDOM_TEXT=One upon a time + +Please also note that ``make`` options can still be passed on the command line, +so while this can't be done since the first argument needs to be the +executable:: + + scripts/container -i docker.io/tuxmake/korg-clang LLVM=1 make # won't work + +this will work:: + + scripts/container -i docker.io/tuxmake/korg-clang make LLVM=1 + + +User IDs +======== + +This is an area where the behaviour will vary slightly depending on the +container runtime. The goal is to run commands as the user invoking the tool. +With Podman, a namespace is created to map the current user id to a different +one in the container (1000 by default). With Docker, while this is also +possible with recent versions it requires a special feature to be enabled in +the daemon so it's not used here for simplicity. Instead, the container is run +with the current user id directly. In both cases, this will provide the same +file permissions for the kernel source tree mounted as a volume. The only +difference is that when using Docker without a namespace, the user id may not +be the same as the default one set in the image. + +Say, we're using an image which sets up a default user with id 1000 and the +current user calling the ``container`` tool has id 1234. The kernel source +tree was checked out by this same user so the files belong to user 1234. With +Podman, the container will be running as user id 1000 with a mapping to id 1234 +so that the files from the mounted volume appear to belong to id 1000 inside +the container. With Docker and no namespace, the container will be running +with user id 1234 which can access the files in the volume but not in the user +1000 home directory. This shouldn't be an issue when running commands only in +the kernel tree but it is worth highlighting here as it might matter for +special corner cases. + +.. note:: + + Podman's `Docker compatibility + <https://podman-desktop.io/docs/migrating-from-docker/managing-docker-compatibility>`__ + mode to run ``docker`` commands on top of a Podman backend is more complex + and not fully supported yet. As such, Podman will take priority if both + runtimes are available on the system. + + +Examples +======== + +The TuxMake project provides a variety of prebuilt container images available +on `Docker Hub <https://hub.docker.com/u/tuxmake>`__. Here's the shortest +example to build a kernel using a TuxMake Clang image:: + + scripts/container -i docker.io/tuxmake/korg-clang -- make LLVM=1 defconfig + scripts/container -i docker.io/tuxmake/korg-clang -- make LLVM=1 -j$(nproc) + +.. note:: + + When running a command with options within the container, it should be + separated with a double dash ``--`` to not confuse them with the + ``container`` tool options. Plain commands with no options don't strictly + require the double dashes e.g.:: + + scripts/container -i docker.io/tuxmake/korg-clang make mrproper + +To run ``checkpatch.pl`` in a ``patches`` directory with a generic Perl image:: + + scripts/container -i perl:slim-trixie scripts/checkpatch.pl patches/* + +As an alternative to the TuxMake images, the examples below refer to +``kernel.org`` images which are based on the `kernel.org compiler toolchains +<https://mirrors.edge.kernel.org/pub/tools/>`__. These aren't (yet) officially +available in any public registry but users can build their own locally instead +using this `experimental repository +<https://gitlab.com/gtucker/korg-containers>`__ by running ``make +PREFIX=kernel.org/``. + +To build just ``bzImage`` using Clang:: + + scripts/container -i kernel.org/clang -- make bzImage -j$(nproc) + +Same with GCC 15 as a particular version tag:: + + scripts/container -i kernel.org/gcc:15 -- make bzImage -j$(nproc) + +For an out-of-tree build, a trick is to bind-mount the destination directory to +a relative path inside the source tree:: + + mkdir -p $HOME/tmp/my-kernel-build + mkdir -p build + sudo mount --bind $HOME/tmp/my-kernel-build build + scripts/container -i kernel.org/gcc -- make mrproper + scripts/container -i kernel.org/gcc -- make O=build defconfig + scripts/container -i kernel.org/gcc -- make O=build -j$(nproc) + +To run KUnit in an interactive shell and get the full output:: + + scripts/container -s -i kernel.org/gcc:kunit -- \ + tools/testing/kunit/kunit.py \ + run \ + --arch=x86_64 \ + --cross_compile=x86_64-linux- + +To just start an interactive shell:: + + scripts/container -si kernel.org/gcc bash + +To build the HTML documentation, which requires the ``kdocs`` image built with +``make PREFIX=kernel.org/ extra`` as it's not a compiler toolchain:: + + scripts/container -i kernel.org/kdocs make htmldocs diff --git a/Documentation/dev-tools/context-analysis.rst b/Documentation/dev-tools/context-analysis.rst new file mode 100644 index 000000000000..54d9ee28de98 --- /dev/null +++ b/Documentation/dev-tools/context-analysis.rst @@ -0,0 +1,169 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. Copyright (C) 2025, Google LLC. + +.. _context-analysis: + +Compiler-Based Context Analysis +=============================== + +Context Analysis is a language extension, which enables statically checking +that required contexts are active (or inactive) by acquiring and releasing +user-definable "context locks". An obvious application is lock-safety checking +for the kernel's various synchronization primitives (each of which represents a +"context lock"), and checking that locking rules are not violated. + +The Clang compiler currently supports the full set of context analysis +features. To enable for Clang, configure the kernel with:: + + CONFIG_WARN_CONTEXT_ANALYSIS=y + +The feature requires Clang 22 or later. + +The analysis is *opt-in by default*, and requires declaring which modules and +subsystems should be analyzed in the respective `Makefile`:: + + CONTEXT_ANALYSIS_mymodule.o := y + +Or for all translation units in the directory:: + + CONTEXT_ANALYSIS := y + +It is possible to enable the analysis tree-wide, however, which will result in +numerous false positive warnings currently and is *not* generally recommended:: + + CONFIG_WARN_CONTEXT_ANALYSIS_ALL=y + +Programming Model +----------------- + +The below describes the programming model around using context lock types. + +.. note:: + Enabling context analysis can be seen as enabling a dialect of Linux C with + a Context System. Some valid patterns involving complex control-flow are + constrained (such as conditional acquisition and later conditional release + in the same function). + +Context analysis is a way to specify permissibility of operations to depend on +context locks being held (or not held). Typically we are interested in +protecting data and code in a critical section by requiring a specific context +to be active, for example by holding a specific lock. The analysis ensures that +callers cannot perform an operation without the required context being active. + +Context locks are associated with named structs, along with functions that +operate on struct instances to acquire and release the associated context lock. + +Context locks can be held either exclusively or shared. This mechanism allows +assigning more precise privileges when a context is active, typically to +distinguish where a thread may only read (shared) or also write (exclusive) to +data guarded within a context. + +The set of contexts that are actually active in a given thread at a given point +in program execution is a run-time concept. The static analysis works by +calculating an approximation of that set, called the context environment. The +context environment is calculated for every program point, and describes the +set of contexts that are statically known to be active, or inactive, at that +particular point. This environment is a conservative approximation of the full +set of contexts that will actually be active in a thread at run-time. + +More details are also documented `here +<https://clang.llvm.org/docs/ThreadSafetyAnalysis.html>`_. + +.. note:: + Clang's analysis explicitly does not infer context locks acquired or + released by inline functions. It requires explicit annotations to (a) assert + that it's not a bug if a context lock is released or acquired, and (b) to + retain consistency between inline and non-inline function declarations. + +Supported Kernel Primitives +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Currently the following synchronization primitives are supported: +`raw_spinlock_t`, `spinlock_t`, `rwlock_t`, `mutex`, `seqlock_t`, +`bit_spinlock`, RCU, SRCU (`srcu_struct`), `rw_semaphore`, `local_lock_t`, +`ww_mutex`. + +To initialize variables guarded by a context lock with an initialization +function (``type_init(&lock)``), prefer using ``guard(type_init)(&lock)`` or +``scoped_guard(type_init, &lock) { ... }`` to initialize such guarded members +or globals in the enclosing scope. This initializes the context lock and treats +the context as active within the initialization scope (initialization implies +exclusive access to the underlying object). + +For example:: + + struct my_data { + spinlock_t lock; + int counter __guarded_by(&lock); + }; + + void init_my_data(struct my_data *d) + { + ... + guard(spinlock_init)(&d->lock); + d->counter = 0; + ... + } + +Alternatively, initializing guarded variables can be done with context analysis +disabled, preferably in the smallest possible scope (due to lack of any other +checking): either with a ``context_unsafe(var = init)`` expression, or by +marking small initialization functions with the ``__context_unsafe(init)`` +attribute. + +Lockdep assertions, such as `lockdep_assert_held()`, inform the compiler's +context analysis that the associated synchronization primitive is held after +the assertion. This avoids false positives in complex control-flow scenarios +and encourages the use of Lockdep where static analysis is limited. For +example, this is useful when a function doesn't *always* require a lock, making +`__must_hold()` inappropriate. + +Keywords +~~~~~~~~ + +.. kernel-doc:: include/linux/compiler-context-analysis.h + :identifiers: context_lock_struct + token_context_lock token_context_lock_instance + __guarded_by __pt_guarded_by + __must_hold + __must_not_hold + __acquires + __cond_acquires + __releases + __must_hold_shared + __acquires_shared + __cond_acquires_shared + __releases_shared + __acquire + __release + __acquire_shared + __release_shared + __acquire_ret + __acquire_shared_ret + context_unsafe + __context_unsafe + disable_context_analysis enable_context_analysis + +.. note:: + The function attribute `__no_context_analysis` is reserved for internal + implementation of context lock types, and should be avoided in normal code. + +Background +---------- + +Clang originally called the feature `Thread Safety Analysis +<https://clang.llvm.org/docs/ThreadSafetyAnalysis.html>`_, with some keywords +and documentation still using the thread-safety-analysis-only terminology. This +was later changed and the feature became more flexible, gaining the ability to +define custom "capabilities". Its foundations can be found in `Capability +Systems <https://www.cs.cornell.edu/talc/papers/capabilities.pdf>`_, used to +specify the permissibility of operations to depend on some "capability" being +held (or not held). + +Because the feature is not just able to express capabilities related to +synchronization primitives, and "capability" is already overloaded in the +kernel, the naming chosen for the kernel departs from Clang's initial "Thread +Safety" and "capability" nomenclature; we refer to the feature as "Context +Analysis" to avoid confusion. The internal implementation still makes +references to Clang's terminology in a few places, such as `-Wthread-safety` +being the warning option that also still appears in diagnostic messages. diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/index.rst index 65c54b27a60b..59cbb77b33ff 100644 --- a/Documentation/dev-tools/index.rst +++ b/Documentation/dev-tools/index.rst @@ -21,6 +21,7 @@ Documentation/process/debugging/index.rst checkpatch clang-format coccinelle + context-analysis sparse kcov gcov @@ -29,6 +30,7 @@ Documentation/process/debugging/index.rst ubsan kmemleak kcsan + lkmm/index kfence kselftest kunit/index @@ -37,11 +39,4 @@ Documentation/process/debugging/index.rst gpio-sloppy-logic-analyzer autofdo propeller - - -.. only:: subproject and html - - Indices - ======= - - * :ref:`genindex` + container diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst index 0a1418ab72fd..4968b2aa60c8 100644 --- a/Documentation/dev-tools/kasan.rst +++ b/Documentation/dev-tools/kasan.rst @@ -75,9 +75,6 @@ Software Tag-Based KASAN supports slab, page_alloc, vmalloc, and stack memory. Hardware Tag-Based KASAN supports slab, page_alloc, and non-executable vmalloc memory. -For slab, both software KASAN modes support SLUB and SLAB allocators, while -Hardware Tag-Based KASAN only supports SLUB. - Usage ----- @@ -143,6 +140,9 @@ disabling KASAN altogether or controlling its features: Asymmetric mode: a bad access is detected synchronously on reads and asynchronously on writes. +- ``kasan.write_only=off`` or ``kasan.write_only=on`` controls whether KASAN + checks the write (store) accesses only or all accesses (default: ``off``). + - ``kasan.vmalloc=off`` or ``=on`` disables or enables tagging of vmalloc allocations (default: ``on``). diff --git a/Documentation/dev-tools/kcov.rst b/Documentation/dev-tools/kcov.rst index 6611434e2dd2..8127849d40f5 100644 --- a/Documentation/dev-tools/kcov.rst +++ b/Documentation/dev-tools/kcov.rst @@ -361,7 +361,12 @@ local tasks spawned by the process and the global task that handles USB bus #1: */ sleep(2); - n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED); + /* + * The load to the coverage count should be an acquire to pair with + * pair with the corresponding write memory barrier (smp_wmb()) on + * the kernel-side in kcov_move_area(). + */ + n = __atomic_load_n(&cover[0], __ATOMIC_ACQUIRE); for (i = 0; i < n; i++) printf("0x%lx\n", cover[i + 1]); if (ioctl(fd, KCOV_DISABLE, 0)) diff --git a/Documentation/dev-tools/kfence.rst b/Documentation/dev-tools/kfence.rst index 541899353865..b03d1201ddae 100644 --- a/Documentation/dev-tools/kfence.rst +++ b/Documentation/dev-tools/kfence.rst @@ -81,6 +81,13 @@ tables being allocated. Error reports ~~~~~~~~~~~~~ +The boot parameter ``kfence.fault`` can be used to control the behavior when a +KFENCE error is detected: + +- ``kfence.fault=report``: Print the error report and continue (default). +- ``kfence.fault=oops``: Print the error report and oops. +- ``kfence.fault=panic``: Print the error report and panic. + A typical out-of-bounds access looks like this:: ================================================================== diff --git a/Documentation/dev-tools/ktap.rst b/Documentation/dev-tools/ktap.rst index 414c105b10a9..a9810bed5fd4 100644 --- a/Documentation/dev-tools/ktap.rst +++ b/Documentation/dev-tools/ktap.rst @@ -5,7 +5,7 @@ The Kernel Test Anything Protocol (KTAP), version 1 =================================================== TAP, or the Test Anything Protocol is a format for specifying test results used -by a number of projects. It's website and specification are found at this `link +by a number of projects. Its website and specification are found at this `link <https://testanything.org/>`_. The Linux Kernel largely uses TAP output for test results. However, Kernel testing frameworks have special needs for test results which don't align with the original TAP specification. Thus, a "Kernel TAP" @@ -20,6 +20,7 @@ machine-readable, whereas the diagnostic data is unstructured and is there to aid human debugging. KTAP output is built from four different types of lines: + - Version lines - Plan lines - Test case result lines @@ -38,6 +39,7 @@ All KTAP-formatted results begin with a "version line" which specifies which version of the (K)TAP standard the result is compliant with. For example: + - "KTAP version 1" - "TAP version 13" - "TAP version 14" @@ -276,6 +278,7 @@ Example KTAP output This output defines the following hierarchy: A single test called "main_test", which fails, and has three subtests: + - "example_test_1", which passes, and has one subtest: - "test_1", which passes, and outputs the diagnostic message "test_1: initializing test_1" diff --git a/Documentation/dev-tools/kunit/run_manual.rst b/Documentation/dev-tools/kunit/run_manual.rst index 699d92885075..98e8d5b28808 100644 --- a/Documentation/dev-tools/kunit/run_manual.rst +++ b/Documentation/dev-tools/kunit/run_manual.rst @@ -35,6 +35,12 @@ or be built into the kernel. a good way of quickly testing everything applicable to the current config. + KUnit can be enabled or disabled at boot time, and this behavior is + controlled by the kunit.enable kernel parameter. + By default, kunit.enable is set to 1 because KUNIT_DEFAULT_ENABLED is + enabled by default. To ensure that tests are executed as expected, + verify that kunit.enable=1 at boot time. + Once we have built our kernel (and/or modules), it is simple to run the tests. If the tests are built-in, they will run automatically on the kernel boot. The results will be written to the kernel log (``dmesg``) diff --git a/Documentation/dev-tools/kunit/run_wrapper.rst b/Documentation/dev-tools/kunit/run_wrapper.rst index 19ddf5e07013..770bb09a475a 100644 --- a/Documentation/dev-tools/kunit/run_wrapper.rst +++ b/Documentation/dev-tools/kunit/run_wrapper.rst @@ -182,6 +182,8 @@ via UML. To run tests on qemu, by default it requires two flags: is ignored), the tests will run via UML. Non-UML architectures, for example: i386, x86_64, arm and so on; run on qemu. + ``--arch help`` lists all valid ``--arch`` values. + - ``--cross_compile``: Specifies the Kbuild toolchain. It passes the same argument as passed to the ``CROSS_COMPILE`` variable used by Kbuild. As a reminder, this will be the prefix for the toolchain @@ -333,3 +335,14 @@ command line arguments: - ``--list_tests_attr``: If set, lists all tests that will be run and all of their attributes. + +- ``--list_suites``: If set, lists all suites that will be run. + +Command-line completion +============================== + +The kunit_tool comes with a bash completion script: + +.. code-block:: bash + + source tools/testing/kunit/kunit-completion.sh diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-tools/kunit/usage.rst index 22955d56b379..ebd06f5ea455 100644 --- a/Documentation/dev-tools/kunit/usage.rst +++ b/Documentation/dev-tools/kunit/usage.rst @@ -542,11 +542,31 @@ There is more boilerplate code involved, but it can: Parameterized Testing ~~~~~~~~~~~~~~~~~~~~~ -The table-driven testing pattern is common enough that KUnit has special -support for it. +To run a test case against multiple inputs, KUnit provides a parameterized +testing framework. This feature formalizes and extends the concept of +table-driven tests discussed previously. -By reusing the same ``cases`` array from above, we can write the test as a -"parameterized test" with the following. +A KUnit test is determined to be parameterized if a parameter generator function +is provided when registering the test case. A test user can either write their +own generator function or use one that is provided by KUnit. The generator +function is stored in ``kunit_case->generate_params`` and can be set using the +macros described in the section below. + +To establish the terminology, a "parameterized test" is a test which is run +multiple times (once per "parameter" or "parameter run"). Each parameter run has +both its own independent ``struct kunit`` (the "parameter run context") and +access to a shared parent ``struct kunit`` (the "parameterized test context"). + +Passing Parameters to a Test +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +There are three ways to provide the parameters to a test: + +Array Parameter Macros: + + KUnit provides special support for the common table-driven testing pattern. + By applying either ``KUNIT_ARRAY_PARAM`` or ``KUNIT_ARRAY_PARAM_DESC`` to the + ``cases`` array from the previous section, we can create a parameterized test + as shown below: .. code-block:: c @@ -555,7 +575,7 @@ By reusing the same ``cases`` array from above, we can write the test as a const char *str; const char *sha1; }; - const struct sha1_test_case cases[] = { + static const struct sha1_test_case cases[] = { { .str = "hello world", .sha1 = "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", @@ -590,6 +610,318 @@ By reusing the same ``cases`` array from above, we can write the test as a {} }; +Custom Parameter Generator Function: + + The generator function is responsible for generating parameters one-by-one + and has the following signature: + ``const void* (*)(struct kunit *test, const void *prev, char *desc)``. + You can pass the generator function to the ``KUNIT_CASE_PARAM`` + or ``KUNIT_CASE_PARAM_WITH_INIT`` macros. + + The function receives the previously generated parameter as the ``prev`` argument + (which is ``NULL`` on the first call) and can also access the parameterized + test context passed as the ``test`` argument. KUnit calls this function + repeatedly until it returns ``NULL``, which signifies that a parameterized + test ended. + + Below is an example of how it works: + +.. code-block:: c + + #define MAX_TEST_BUFFER_SIZE 8 + + // Example generator function. It produces a sequence of buffer sizes that + // are powers of two, starting at 1 (e.g., 1, 2, 4, 8). + static const void *buffer_size_gen_params(struct kunit *test, const void *prev, char *desc) + { + long prev_buffer_size = (long)prev; + long next_buffer_size = 1; // Start with an initial size of 1. + + // Stop generating parameters if the limit is reached or exceeded. + if (prev_buffer_size >= MAX_TEST_BUFFER_SIZE) + return NULL; + + // For subsequent calls, calculate the next size by doubling the previous one. + if (prev) + next_buffer_size = prev_buffer_size << 1; + + return (void *)next_buffer_size; + } + + // Simple test to validate that kunit_kzalloc provides zeroed memory. + static void buffer_zero_test(struct kunit *test) + { + long buffer_size = (long)test->param_value; + // Use kunit_kzalloc to allocate a zero-initialized buffer. This makes the + // memory "parameter run managed," meaning it's automatically cleaned up at + // the end of each parameter run. + int *buf = kunit_kzalloc(test, buffer_size * sizeof(int), GFP_KERNEL); + + // Ensure the allocation was successful. + KUNIT_ASSERT_NOT_NULL(test, buf); + + // Loop through the buffer and confirm every element is zero. + for (int i = 0; i < buffer_size; i++) + KUNIT_EXPECT_EQ(test, buf[i], 0); + } + + static struct kunit_case buffer_test_cases[] = { + KUNIT_CASE_PARAM(buffer_zero_test, buffer_size_gen_params), + {} + }; + +Runtime Parameter Array Registration in the Init Function: + + For scenarios where you might need to initialize a parameterized test, you + can directly register a parameter array to the parameterized test context. + + To do this, you must pass the parameterized test context, the array itself, + the array size, and a ``get_description()`` function to the + ``kunit_register_params_array()`` macro. This macro populates + ``struct kunit_params`` within the parameterized test context, effectively + storing a parameter array object. The ``get_description()`` function will + be used for populating parameter descriptions and has the following signature: + ``void (*)(struct kunit *test, const void *param, char *desc)``. Note that it + also has access to the parameterized test context. + + .. important:: + When using this way to register a parameter array, you will need to + manually pass ``kunit_array_gen_params()`` as the generator function to + ``KUNIT_CASE_PARAM_WITH_INIT``. ``kunit_array_gen_params()`` is a KUnit + helper that will use the registered array to generate the parameters. + + If needed, instead of passing the KUnit helper, you can also pass your + own custom generator function that utilizes the parameter array. To + access the parameter array from within the parameter generator + function use ``test->params_array.params``. + + The ``kunit_register_params_array()`` macro should be called within a + ``param_init()`` function that initializes the parameterized test and has + the following signature ``int (*)(struct kunit *test)``. For a detailed + explanation of this mechanism please refer to the "Adding Shared Resources" + section that is after this one. This method supports registering both + dynamically built and static parameter arrays. + + The code snippet below shows the ``example_param_init_dynamic_arr`` test that + utilizes ``make_fibonacci_params()`` to create a dynamic array, which is then + registered using ``kunit_register_params_array()``. To see the full code + please refer to lib/kunit/kunit-example-test.c. + +.. code-block:: c + + /* + * Example of a parameterized test param_init() function that registers a dynamic + * array of parameters. + */ + static int example_param_init_dynamic_arr(struct kunit *test) + { + size_t seq_size; + int *fibonacci_params; + + kunit_info(test, "initializing parameterized test\n"); + + seq_size = 6; + fibonacci_params = make_fibonacci_params(test, seq_size); + if (!fibonacci_params) + return -ENOMEM; + /* + * Passes the dynamic parameter array information to the parameterized test + * context struct kunit. The array and its metadata will be stored in + * test->parent->params_array. The array itself will be located in + * params_data.params. + */ + kunit_register_params_array(test, fibonacci_params, seq_size, + example_param_dynamic_arr_get_desc); + return 0; + } + + static struct kunit_case example_test_cases[] = { + /* + * Note how we pass kunit_array_gen_params() to use the array we + * registered in example_param_init_dynamic_arr() to generate + * parameters. + */ + KUNIT_CASE_PARAM_WITH_INIT(example_params_test_with_init_dynamic_arr, + kunit_array_gen_params, + example_param_init_dynamic_arr, + example_param_exit_dynamic_arr), + {} + }; + +Adding Shared Resources +^^^^^^^^^^^^^^^^^^^^^^^ +All parameter runs in this framework hold a reference to the parameterized test +context, which can be accessed using the parent ``struct kunit`` pointer. The +parameterized test context is not used to execute any test logic itself; instead, +it serves as a container for shared resources. + +It's possible to add resources to share between parameter runs within a +parameterized test by using ``KUNIT_CASE_PARAM_WITH_INIT``, to which you pass +custom ``param_init()`` and ``param_exit()`` functions. These functions run once +before and once after the parameterized test, respectively. + +The ``param_init()`` function, with the signature ``int (*)(struct kunit *test)``, +can be used for adding resources to the ``resources`` or ``priv`` fields of +the parameterized test context, registering the parameter array, and any other +initialization logic. + +The ``param_exit()`` function, with the signature ``void (*)(struct kunit *test)``, +can be used to release any resources that were not parameterized test managed (i.e. +not automatically cleaned up after the parameterized test ends) and for any other +exit logic. + +Both ``param_init()`` and ``param_exit()`` are passed the parameterized test +context behind the scenes. However, the test case function receives the parameter +run context. Therefore, to manage and access shared resources from within a test +case function, you must use ``test->parent``. + +For instance, finding a shared resource allocated by the Resource API requires +passing ``test->parent`` to ``kunit_find_resource()``. This principle extends to +all other APIs that might be used in the test case function, including +``kunit_kzalloc()``, ``kunit_kmalloc_array()``, and others (see +Documentation/dev-tools/kunit/api/test.rst and the +Documentation/dev-tools/kunit/api/resource.rst). + +.. note:: + The ``suite->init()`` function, which executes before each parameter run, + receives the parameter run context. Therefore, any resources set up in + ``suite->init()`` are cleaned up after each parameter run. + +The code below shows how you can add the shared resources. Note that this code +utilizes the Resource API, which you can read more about here: +Documentation/dev-tools/kunit/api/resource.rst. To see the full version of this +code please refer to lib/kunit/kunit-example-test.c. + +.. code-block:: c + + static int example_resource_init(struct kunit_resource *res, void *context) + { + ... /* Code that allocates memory and stores context in res->data. */ + } + + /* This function deallocates memory for the kunit_resource->data field. */ + static void example_resource_free(struct kunit_resource *res) + { + kfree(res->data); + } + + /* This match function locates a test resource based on defined criteria. */ + static bool example_resource_alloc_match(struct kunit *test, struct kunit_resource *res, + void *match_data) + { + return res->data && res->free == example_resource_free; + } + + /* Function to initialize the parameterized test. */ + static int example_param_init(struct kunit *test) + { + int ctx = 3; /* Data to be stored. */ + void *data = kunit_alloc_resource(test, example_resource_init, + example_resource_free, + GFP_KERNEL, &ctx); + if (!data) + return -ENOMEM; + kunit_register_params_array(test, example_params_array, + ARRAY_SIZE(example_params_array)); + return 0; + } + + /* Example test that uses shared resources in test->resources. */ + static void example_params_test_with_init(struct kunit *test) + { + int threshold; + const struct example_param *param = test->param_value; + /* Here we pass test->parent to access the parameterized test context. */ + struct kunit_resource *res = kunit_find_resource(test->parent, + example_resource_alloc_match, + NULL); + + threshold = *((int *)res->data); + KUNIT_ASSERT_LE(test, param->value, threshold); + kunit_put_resource(res); + } + + static struct kunit_case example_test_cases[] = { + KUNIT_CASE_PARAM_WITH_INIT(example_params_test_with_init, kunit_array_gen_params, + example_param_init, NULL), + {} + }; + +As an alternative to using the KUnit Resource API for sharing resources, you can +place them in ``test->parent->priv``. This serves as a more lightweight method +for resource storage, best for scenarios where complex resource management is +not required. + +As stated previously ``param_init()`` and ``param_exit()`` get the parameterized +test context. So, you can directly use ``test->priv`` within ``param_init/exit`` +to manage shared resources. However, from within the test case function, you must +navigate up to the parent ``struct kunit`` i.e. the parameterized test context. +Therefore, you need to use ``test->parent->priv`` to access those same +resources. + +The resources placed in ``test->parent->priv`` will need to be allocated in +memory to persist across the parameter runs. If memory is allocated using the +KUnit memory allocation APIs (described more in the "Allocating Memory" section +below), you won't need to worry about deallocation. The APIs will make the memory +parameterized test 'managed', ensuring that it will automatically get cleaned up +after the parameterized test concludes. + +The code below demonstrates example usage of the ``priv`` field for shared +resources: + +.. code-block:: c + + static const struct example_param { + int value; + } example_params_array[] = { + { .value = 3, }, + { .value = 2, }, + { .value = 1, }, + { .value = 0, }, + }; + + /* Initialize the parameterized test context. */ + static int example_param_init_priv(struct kunit *test) + { + int ctx = 3; /* Data to be stored. */ + int arr_size = ARRAY_SIZE(example_params_array); + + /* + * Allocate memory using kunit_kzalloc(). Since the `param_init` + * function receives the parameterized test context, this memory + * allocation will be scoped to the lifetime of the parameterized test. + */ + test->priv = kunit_kzalloc(test, sizeof(int), GFP_KERNEL); + + /* Assign the context value to test->priv.*/ + *((int *)test->priv) = ctx; + + /* Register the parameter array. */ + kunit_register_params_array(test, example_params_array, arr_size, NULL); + return 0; + } + + static void example_params_test_with_init_priv(struct kunit *test) + { + int threshold; + const struct example_param *param = test->param_value; + + /* By design, test->parent will not be NULL. */ + KUNIT_ASSERT_NOT_NULL(test, test->parent); + + /* Here we use test->parent->priv to access the shared resource. */ + threshold = *(int *)test->parent->priv; + + KUNIT_ASSERT_LE(test, param->value, threshold); + } + + static struct kunit_case example_tests[] = { + KUNIT_CASE_PARAM_WITH_INIT(example_params_test_with_init_priv, + kunit_array_gen_params, + example_param_init_priv, NULL), + {} + }; + Allocating Memory ----------------- @@ -670,28 +1002,50 @@ with ``kunit_remove_action``. Testing Static Functions ------------------------ -If we do not want to expose functions or variables for testing, one option is to -conditionally export the used symbol. For example: +If you want to test static functions without exposing those functions outside of +testing, one option is conditionally export the symbol. When KUnit is enabled, +the symbol is exposed but remains static otherwise. To use this method, follow +the template below. .. code-block:: c - /* In my_file.c */ + /* In the file containing functions to test "my_file.c" */ - VISIBLE_IF_KUNIT int do_interesting_thing(); + #include <kunit/visibility.h> + #include <my_file.h> + ... + VISIBLE_IF_KUNIT int do_interesting_thing() + { + ... + } EXPORT_SYMBOL_IF_KUNIT(do_interesting_thing); - /* In my_file.h */ + /* In the header file "my_file.h" */ #if IS_ENABLED(CONFIG_KUNIT) int do_interesting_thing(void); #endif -Alternatively, you could conditionally ``#include`` the test file at the end of -your .c file. For example: + /* In the KUnit test file "my_file_test.c" */ + + #include <kunit/visibility.h> + #include <my_file.h> + ... + MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); + ... + // Use do_interesting_thing() in tests + +For a full example, see this `patch <https://lore.kernel.org/all/20221207014024.340230-3-rmoar@google.com/>`_ +where a test is modified to conditionally expose static functions for testing +using the macros above. + +As an **alternative** to the method above, you could conditionally ``#include`` +the test file at the end of your .c file. This is not recommended but works +if needed. For example: .. code-block:: c - /* In my_file.c */ + /* In "my_file.c" */ static int do_interesting_thing(); diff --git a/Documentation/dev-tools/lkmm/docs/access-marking.rst b/Documentation/dev-tools/lkmm/docs/access-marking.rst new file mode 100644 index 000000000000..80058a4da980 --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/access-marking.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Access Marking +-------------- + +Literal include of ``tools/memory-model/Documentation/access-marking.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/access-marking.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/cheatsheet.rst b/Documentation/dev-tools/lkmm/docs/cheatsheet.rst new file mode 100644 index 000000000000..37681f6a6a8c --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/cheatsheet.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Cheatsheet +---------- + +Literal include of ``tools/memory-model/Documentation/cheatsheet.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/cheatsheet.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/control-dependencies.rst b/Documentation/dev-tools/lkmm/docs/control-dependencies.rst new file mode 100644 index 000000000000..5ae97e8861eb --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/control-dependencies.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Control Dependencies +-------------------- + +Literal include of ``tools/memory-model/Documentation/control-dependencies.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/control-dependencies.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/explanation.rst b/Documentation/dev-tools/lkmm/docs/explanation.rst new file mode 100644 index 000000000000..0bcba9a5ddf7 --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/explanation.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Explanation +----------- + +Literal include of ``tools/memory-model/Documentation/explanation.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/explanation.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/glossary.rst b/Documentation/dev-tools/lkmm/docs/glossary.rst new file mode 100644 index 000000000000..849aefdf3d6e --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/glossary.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Glossary +-------- + +Literal include of ``tools/memory-model/Documentation/glossary.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/glossary.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/herd-representation.rst b/Documentation/dev-tools/lkmm/docs/herd-representation.rst new file mode 100644 index 000000000000..f7b41f286eb9 --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/herd-representation.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +herd-representation +------------------- + +Literal include of ``tools/memory-model/Documentation/herd-representation.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/herd-representation.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/index.rst b/Documentation/dev-tools/lkmm/docs/index.rst new file mode 100644 index 000000000000..abbddcc009de --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/index.rst @@ -0,0 +1,21 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Documentation +============= + +.. toctree:: + :maxdepth: 1 + + readme + simple + ordering + litmus-tests + locking + recipes + control-dependencies + access-marking + cheatsheet + explanation + herd-representation + glossary + references diff --git a/Documentation/dev-tools/lkmm/docs/litmus-tests.rst b/Documentation/dev-tools/lkmm/docs/litmus-tests.rst new file mode 100644 index 000000000000..3293f4540156 --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/litmus-tests.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Litmus Tests +------------ + +Literal include of ``tools/memory-model/Documentation/litmus-tests.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/litmus-tests.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/locking.rst b/Documentation/dev-tools/lkmm/docs/locking.rst new file mode 100644 index 000000000000..b5eae4c0acb7 --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/locking.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Locking +------- + +Literal include of ``tools/memory-model/Documentation/locking.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/locking.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/ordering.rst b/Documentation/dev-tools/lkmm/docs/ordering.rst new file mode 100644 index 000000000000..a2343c12462d --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/ordering.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Ordering +-------- + +Literal include of ``tools/memory-model/Documentation/ordering.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/ordering.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/readme.rst b/Documentation/dev-tools/lkmm/docs/readme.rst new file mode 100644 index 000000000000..51e7a64e4435 --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/readme.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +README (for LKMM Documentation) +------------------------------- + +Literal include of ``tools/memory-model/Documentation/README``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/README + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/recipes.rst b/Documentation/dev-tools/lkmm/docs/recipes.rst new file mode 100644 index 000000000000..e55952640047 --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/recipes.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Recipes +------- + +Literal include of ``tools/memory-model/Documentation/recipes.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/recipes.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/references.rst b/Documentation/dev-tools/lkmm/docs/references.rst new file mode 100644 index 000000000000..c6831b3c9c02 --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/references.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +References +---------- + +Literal include of ``tools/memory-model/Documentation/references.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/references.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/docs/simple.rst b/Documentation/dev-tools/lkmm/docs/simple.rst new file mode 100644 index 000000000000..5c1094c95f45 --- /dev/null +++ b/Documentation/dev-tools/lkmm/docs/simple.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Simple +------ + +Literal include of ``tools/memory-model/Documentation/simple.txt``. + +------------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/Documentation/simple.txt + :literal: diff --git a/Documentation/dev-tools/lkmm/index.rst b/Documentation/dev-tools/lkmm/index.rst new file mode 100644 index 000000000000..e52782449ca3 --- /dev/null +++ b/Documentation/dev-tools/lkmm/index.rst @@ -0,0 +1,15 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============================================ +Linux Kernel Memory Consistency Model (LKMM) +============================================ + +This section literally renders documents under ``tools/memory-model/`` +and ``tools/memory-model/Documentation/``, which are maintained in +the *pure* plain text form. + +.. toctree:: + :maxdepth: 2 + + readme + docs/index diff --git a/Documentation/dev-tools/lkmm/readme.rst b/Documentation/dev-tools/lkmm/readme.rst new file mode 100644 index 000000000000..a7f847109584 --- /dev/null +++ b/Documentation/dev-tools/lkmm/readme.rst @@ -0,0 +1,11 @@ +.. SPDX-License-Identifier: GPL-2.0 + +README (for LKMM) +================= + +Literal include of ``tools/memory-model/README``. + +------------------------------------------------------------ + +.. kernel-include:: tools/memory-model/README + :literal: diff --git a/Documentation/dev-tools/sparse.rst b/Documentation/dev-tools/sparse.rst index dc791c8d84d1..37b20170835d 100644 --- a/Documentation/dev-tools/sparse.rst +++ b/Documentation/dev-tools/sparse.rst @@ -53,25 +53,6 @@ sure that bitwise types don't get mixed up (little-endian vs big-endian vs cpu-endian vs whatever), and there the constant "0" really _is_ special. -Using sparse for lock checking ------------------------------- - -The following macros are undefined for gcc and defined during a sparse -run to use the "context" tracking feature of sparse, applied to -locking. These annotations tell sparse when a lock is held, with -regard to the annotated function's entry and exit. - -__must_hold - The specified lock is held on function entry and exit. - -__acquires - The specified lock is held on function exit, but not entry. - -__releases - The specified lock is held on function entry, but not exit. - -If the function enters and exits without the lock held, acquiring and -releasing the lock inside the function in a balanced way, no -annotation is needed. The three annotations above are for cases where -sparse would otherwise report a context imbalance. - Getting sparse -------------- |
