Re: [PATCH v4 08/38] docs: filesystems: update mmap_prepare docs for discontig kernel pgs
From: Suren Baghdasaryan
Date: Sun Oct 04 2026 - 13:15:18 EST
On Sat, Oct 3, 2026 at 6:35 PM Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx> wrote:
>
> Describe the newly introduced discontiguous kernel page mapping mechanism,
> detailing how to use it sensibly and how the API looks.
>
> Explicitly detail the various discontiguous actions available and how to
> use them.
>
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
Reviewed-by: Suren Baghdasaryan <surenb@xxxxxxxxxx>
> ---
> Documentation/filesystems/mmap_prepare.rst | 81 ++++++++++++++++++++++++++++++
> 1 file changed, 81 insertions(+)
>
> diff --git a/Documentation/filesystems/mmap_prepare.rst b/Documentation/filesystems/mmap_prepare.rst
> index 82c99c95ad85..ddb4434d919a 100644
> --- a/Documentation/filesystems/mmap_prepare.rst
> +++ b/Documentation/filesystems/mmap_prepare.rst
> @@ -164,5 +164,86 @@ pointer. These are:
> sufficient entries in the page array to cover the entire range of the
> described VMA.
>
> +* mmap_action_map_discontig_kernel_pages() - Maps a discontiguous range of
> + `struct page` pointers over the VMA. They must span from the start of the VMA,
> + but may terminate prior to the end (leaving the remainder unmapped).
> +
> **NOTE:** The ``action`` field should never normally be manipulated directly,
> rather you ought to use one of these helpers.
> +
> +Discontiguous Actions
> +=====================
> +
> +Some actions can be performed across discontiguous ranges.
> +
> +Map kernel pages
> +----------------
> +
> +To map kernel pages discontiguously, you must provide hooks using ``struct
> +discontig_kernel_page_ops``:
> +
> +.. code-block:: C
> +
> + struct discontig_kernel_page_ops {
> + int (*init)(void *vm_private_data, void **private);
> + int (*get)(struct discontig_kernel_page_state *state);
> + };
> +
> +The ``init`` hook is optional and allows state to be established before the
> +operation starts, for instance taking a reference count. Nothing is invoked
> +after the operation, so ``init`` must not leave locks held, and state that must
> +be released once the mapping goes away should be released in
> +``vm_ops->close``.
> +
> +The ``init`` hook, if provided, is invoked prior to the operation starting. It
> +may update what is pointed to by ``vm_private_data`` and/or ``private``. If an
> +error is returned, then the operation is aborted. The ``private`` field can be
> +reassigned.
> +
> +**NOTE:** The operation may sleep between invocations of ``get``, so locks
> +needed to stabilise state must be taken and released within each hook.
> +
> +The ``get`` handler is the key means through which the operation is
> +executed. The current state of the operation is provided through ``struct
> +discontig_kernel_page_state``:
> +
> +.. code-block:: C
> +
> + struct discontig_kernel_page_state {
> + /* Map state. */
> + unsigned long start; /* Start address of VMA. */
> + unsigned long end; /* End address of VMA. */
> + unsigned long addr; /* The current address to be mapped. */
> + pgoff_t pgoff; /* The current pgoff to be mapped. */
> + unsigned long nr_pages_mapped; /* The number of pages mapped. */
> + unsigned long nr_pages_remain; /* The number of pages remaining. */
> +
> + /* User-defined state. */
> + void *vm_private_data; /* VMA private data. */
> + void *private; /* Mapping private data. */
> +
> + /* Users should not touch these, use discontig_kernel_map_*() helpers. */
> + ... internal fields ...
> + };
> +
> +With ``private`` being an additional user-controllable state variable,
> +initialised via ``mmap_action_map_discontig_kernel_pages()``, and
> +``vm_private_data`` being equal to the ``desc->private_data`` field set in
> +the ``mmap_prepare()`` hook.
> +
> +In the ``get`` hook, the user must choose how to map kernel pages:
> +
> +* ``discontig_kernel_map_abort()`` - Call this to abort the operation, whatever
> + has been mapped so far will be retained, the rest of the mapping will SIGBUS
> + if accessed.
> +* ``discontig_kernel_map_page()`` - Maps a single page, correctly handling
> + compound pages (if the compound page is bigger than the remaining pages in the
> + VMA, then only those pages that fit will be mapped). For a compound page, the
> + head page must be passed.
> +* ``discontig_kernel_map_page_range()`` - Map an array of pages of a specified
> + size. As with a compound page, if more pages are specified than remain in
> + the VMA then only those that fit will be mapped.
> +
> +If an error arises after ``init`` succeeded, the core unmaps the VMA, invoking
> +``vm_ops->close`` if set, which is therefore the place to release any state
> +that ``init`` established.
>
> --
> 2.55.0
>