Re: [PATCH 2/2] docs/mm: Physical Memory: add structure, introduction and nodes description

From: Bagas Sanjaya
Date: Fri Jan 06 2023 - 22:55:38 EST


On Sun, Jan 01, 2023 at 11:45:23AM +0200, Mike Rapoport wrote:
> From: "Mike Rapoport (IBM)" <rppt@xxxxxxxxxx>
>

No patch description really?

> +Each node may be divided up into a number of blocks called zones which
> +represent ranges within memory. These ranges are usually determined by
> +architectural constraints for accessing the physical memory. A zone is
> +described by a ``struct zone_struct``, typedeffed to ``zone_t`` and each zone
> +has one of the types described below.
> +
> +`ZONE_DMA` and `ZONE_DMA32`
> + represent memory suitable for DMA by peripheral devices that cannot
> + access all of the addressable memory. Depending on the architecture,
> + either of these zone types or even they both can be disabled at build
> + time using ``CONFIG_ZONE_DMA`` and ``CONFIG_ZONE_DMA32`` configuration
> + options. Some 64-bit platforms may need both zones as they support
> + peripherals with different DMA addressing limitations.
> +
> +`ZONE_NORMAL`
> + is for normal memory that can be accessed by the kernel all the time. DMA
> + operations can be performed on pages in this zone if the DMA devices support
> + transfers to all addressable memory. ZONE_NORMAL is always enabled.
> +
> +`ZONE_HIGHMEM`
> + is the part of the physical memory that is not covered by a permanent mapping
> + in the kernel page tables. The memory in this zone is only accessible to the
> + kernel using temporary mappings. This zone is available only some 32-bit
> + architectures and is enabled with ``CONFIG_HIGHMEM``.
> +
> +`ZONE_MOVABLE`
> + is for normal accessible memory, just like ZONE_NORMAL. The difference is
> + that most pages in ZONE_MOVABLE are movable. That means that while virtual
> + addresses of these pages do not change, their content may move between
> + different physical pages. ZONE_MOVABLE is only enabled when one of
> + `kernelcore`, `movablecore` and `movable_node` parameters is present in the
> + kernel command line. See :ref:`Page migration <page_migration>` for
> + additional details.
> +
> +`ZONE_DEVICE`
> + represents memory residing on devices such as PMEM and GPU. It has different
> + characteristics than RAM zone types and it exists to provide :ref:`struct
> + page <Pages>` and memory map services for device driver identified physical
> + address ranges. ZONE_DEVICE is enabled with configuration option
> + ``CONFIG_ZONE_DEVICE``.

I think bullet lists should do the job better, since the zone names are
connected directly to their representations:

---- >8 ----

diff --git a/Documentation/mm/physical_memory.rst b/Documentation/mm/physical_memory.rst
index fcf52f1db16b71..d308b11cfcf7f0 100644
--- a/Documentation/mm/physical_memory.rst
+++ b/Documentation/mm/physical_memory.rst
@@ -35,40 +35,36 @@ architectural constraints for accessing the physical memory. A zone is
described by a ``struct zone_struct``, typedeffed to ``zone_t`` and each zone
has one of the types described below.

-`ZONE_DMA` and `ZONE_DMA32`
- represent memory suitable for DMA by peripheral devices that cannot
- access all of the addressable memory. Depending on the architecture,
- either of these zone types or even they both can be disabled at build
- time using ``CONFIG_ZONE_DMA`` and ``CONFIG_ZONE_DMA32`` configuration
- options. Some 64-bit platforms may need both zones as they support
- peripherals with different DMA addressing limitations.
+* `ZONE_DMA` and `ZONE_DMA32` represent memory suitable for DMA by peripheral
+ devices that cannot access all of the addressable memory. Depending on the
+ architecture, either of these zone types or even they both can be disabled
+ at build time using ``CONFIG_ZONE_DMA`` and ``CONFIG_ZONE_DMA32``
+ configuration options. Some 64-bit platforms may need both zones as they
+ support peripherals with different DMA addressing limitations.

-`ZONE_NORMAL`
- is for normal memory that can be accessed by the kernel all the time. DMA
- operations can be performed on pages in this zone if the DMA devices support
- transfers to all addressable memory. ZONE_NORMAL is always enabled.
+* `ZONE_NORMAL` is for normal memory that can be accessed by the kernel all
+ the time. DMA operations can be performed on pages in this zone if the DMA
+ devices support transfers to all addressable memory. ZONE_NORMAL is always
+ enabled.

-`ZONE_HIGHMEM`
- is the part of the physical memory that is not covered by a permanent mapping
- in the kernel page tables. The memory in this zone is only accessible to the
- kernel using temporary mappings. This zone is available only some 32-bit
- architectures and is enabled with ``CONFIG_HIGHMEM``.
+* `ZONE_HIGHMEM` is the part of the physical memory that is not covered by a
+ permanent mapping in the kernel page tables. The memory in this zone is only
+ accessible to the kernel using temporary mappings. This zone is available
+ only on some 32-bit architectures and is enabled with ``CONFIG_HIGHMEM``.

-`ZONE_MOVABLE`
- is for normal accessible memory, just like ZONE_NORMAL. The difference is
- that most pages in ZONE_MOVABLE are movable. That means that while virtual
- addresses of these pages do not change, their content may move between
- different physical pages. ZONE_MOVABLE is only enabled when one of
+* `ZONE_MOVABLE` is for normal accessible memory, just like ZONE_NORMAL. The
+ difference is that most pages in ZONE_MOVABLE are movable. That means that
+ while virtual addresses of these pages do not change, their content may move
+ between different physical pages. ZONE_MOVABLE is only enabled when one of
`kernelcore`, `movablecore` and `movable_node` parameters is present in the
kernel command line. See :ref:`Page migration <page_migration>` for
additional details.

-`ZONE_DEVICE`
- represents memory residing on devices such as PMEM and GPU. It has different
- characteristics than RAM zone types and it exists to provide :ref:`struct
- page <Pages>` and memory map services for device driver identified physical
- address ranges. ZONE_DEVICE is enabled with configuration option
- ``CONFIG_ZONE_DEVICE``.
+* `ZONE_DEVICE` represents memory residing on devices such as PMEM and GPU.
+ It has different characteristics than RAM zone types and it exists to provide
+ :ref:`struct page <Pages>` and memory map services for device driver
+ identified physical address ranges. ZONE_DEVICE is enabled with configuration
+ option ``CONFIG_ZONE_DEVICE``.

It is important to note that many kernel operations can only take place using
ZONE_NORMAL so it is the most performance critical zone. Zones are discussed

> +For example, with 32-bit kernel on an x86 UMA machine with 2 Gbytes of RAM the
> +entire memory will be on node 0 and there will be three zones: ZONE_DMA,
> +ZONE_NORMAL and ZONE_HIGHMEM::
> +
> + 0 2G
> + +-------------------------------------------------------------+
> + | node 0 |
> + +-------------------------------------------------------------+
> +
> + 0 16M 896M 2G
> + +----------+-----------------------+--------------------------+
> + | ZONE_DMA | ZONE_NORMAL | ZONE_HIGHMEM |
> + +----------+-----------------------+--------------------------+
> +
> +
> +With a kernel built with ZONE_DMA disabled and ZONE_DMA32 enabled and booted
> +with `movablecore=80%` parameter on an arm64 machine with 16 Gbytes of RAM
> +equally split between two nodes, there will be ZONE_DMA32, ZONE_NORMAL and
> +ZONE_MOVABLE on node 0, and ZONE_NORMAL and ZONE_MOVABLE on node 1::
> +
> +
> + 1G 9G 17G
> + +--------------------------------+ +--------------------------+
> + | node 0 | | node 1 |
> + +--------------------------------+ +--------------------------+
> +
> + 1G 4G 4200M 9G 9320M 17G
> + +---------+----------+-----------+ +------------+-------------+
> + | DMA32 | NORMAL | MOVABLE | | NORMAL | MOVABLE |
> + +---------+----------+-----------+ +------------+-------------+

I see inconsistency of formatting keywords: some are in inline code and some
are not. I'm leaning towards inlining them all:

---- >8 ----

diff --git a/Documentation/mm/physical_memory.rst b/Documentation/mm/physical_memory.rst
index d308b11cfcf7f0..83e13166508a20 100644
--- a/Documentation/mm/physical_memory.rst
+++ b/Documentation/mm/physical_memory.rst
@@ -19,14 +19,14 @@ a bank of memory very suitable for DMA near peripheral devices.

Each bank is called a node and the concept is represented under Linux by a
``struct pglist_data`` even if the architecture is UMA. This structure is
-always referenced to by it's typedef ``pg_data_t``. A pg_data_t structure
+always referenced to by it's typedef ``pg_data_t``. ``A pg_data_t`` structure
for a particular node can be referenced by ``NODE_DATA(nid)`` macro where
``nid`` is the ID of that node.

For NUMA architectures, the node structures are allocated by the architecture
specific code early during boot. Usually, these structures are allocated
locally on the memory bank they represent. For UMA architectures, only one
-static pg_data_t structure called ``contig_page_data`` is used. Nodes will
+static ``pg_data_t`` structure called ``contig_page_data`` is used. Nodes will
be discussed further in Section :ref:`Nodes <nodes>`

Each node may be divided up into a number of blocks called zones which
@@ -35,48 +35,49 @@ architectural constraints for accessing the physical memory. A zone is
described by a ``struct zone_struct``, typedeffed to ``zone_t`` and each zone
has one of the types described below.

-* `ZONE_DMA` and `ZONE_DMA32` represent memory suitable for DMA by peripheral
- devices that cannot access all of the addressable memory. Depending on the
- architecture, either of these zone types or even they both can be disabled
- at build time using ``CONFIG_ZONE_DMA`` and ``CONFIG_ZONE_DMA32``
- configuration options. Some 64-bit platforms may need both zones as they
- support peripherals with different DMA addressing limitations.
+* ``ZONE_DMA` and ``ZONE_DMA32`` represent memory suitable for DMA by
+ peripheral devices that cannot access all of the addressable memory.
+ Depending on the architecture, either of these zone types or even they both
+ can be disabled at build time using ``CONFIG_ZONE_DMA`` and
+ ``CONFIG_ZONE_DMA32`` configuration options. Some 64-bit platforms may need
+ both zones as they support peripherals with different DMA addressing
+ limitations.

-* `ZONE_NORMAL` is for normal memory that can be accessed by the kernel all
+* ``ZONE_NORMAL`` is for normal memory that can be accessed by the kernel all
the time. DMA operations can be performed on pages in this zone if the DMA
- devices support transfers to all addressable memory. ZONE_NORMAL is always
- enabled.
+ devices support transfers to all addressable memory. ``ZONE_NORMAL`` is
+ always enabled.

-* `ZONE_HIGHMEM` is the part of the physical memory that is not covered by a
+* ``ZONE_HIGHMEM`` is the part of the physical memory that is not covered by a
permanent mapping in the kernel page tables. The memory in this zone is only
accessible to the kernel using temporary mappings. This zone is available
only on some 32-bit architectures and is enabled with ``CONFIG_HIGHMEM``.

-* `ZONE_MOVABLE` is for normal accessible memory, just like ZONE_NORMAL. The
- difference is that most pages in ZONE_MOVABLE are movable. That means that
- while virtual addresses of these pages do not change, their content may move
- between different physical pages. ZONE_MOVABLE is only enabled when one of
- `kernelcore`, `movablecore` and `movable_node` parameters is present in the
- kernel command line. See :ref:`Page migration <page_migration>` for
- additional details.
+* ``ZONE_MOVABLE`` is for normal accessible memory, just like ``ZONE_NORMAL``.
+ The difference is that most pages in ``ZONE_MOVABLE`` are movable. That means
+ that while virtual addresses of these pages do not change, their content may
+ move between different physical pages. ``ZONE_MOVABLE`` is only enabled when
+ one of ``kernelcore``, ``movablecore`` and ``movable_node`` parameters is
+ present in the kernel command line. See :ref:`Page migration
+ <page_migration>` for additional details.

-* `ZONE_DEVICE` represents memory residing on devices such as PMEM and GPU.
+* ``ZONE_DEVICE`` represents memory residing on devices such as PMEM and GPU.
It has different characteristics than RAM zone types and it exists to provide
:ref:`struct page <Pages>` and memory map services for device driver
- identified physical address ranges. ZONE_DEVICE is enabled with configuration
- option ``CONFIG_ZONE_DEVICE``.
+ identified physical address ranges. ``ZONE_DEVICE`` is enabled with
+ configuration option ``CONFIG_ZONE_DEVICE``.

It is important to note that many kernel operations can only take place using
-ZONE_NORMAL so it is the most performance critical zone. Zones are discussed
-further in Section :ref:`Zones <zones>`.
+``ZONE_NORMAL`` so it is the most performance critical zone. Zones are
+discussed further in Section :ref:`Zones <zones>`.

The relation between node and zone extents is determined by the physical memory
map reported by the firmware, architectural constraints for memory addressing
and certain parameters in the kernel command line.

For example, with 32-bit kernel on an x86 UMA machine with 2 Gbytes of RAM the
-entire memory will be on node 0 and there will be three zones: ZONE_DMA,
-ZONE_NORMAL and ZONE_HIGHMEM::
+entire memory will be on node 0 and there will be three zones: ``ZONE_DMA``,
+``ZONE_NORMAL`` and ``ZONE_HIGHMEM``::

0 2G
+-------------------------------------------------------------+
@@ -89,10 +90,11 @@ ZONE_NORMAL and ZONE_HIGHMEM::
+----------+-----------------------+--------------------------+


-With a kernel built with ZONE_DMA disabled and ZONE_DMA32 enabled and booted
-with `movablecore=80%` parameter on an arm64 machine with 16 Gbytes of RAM
-equally split between two nodes, there will be ZONE_DMA32, ZONE_NORMAL and
-ZONE_MOVABLE on node 0, and ZONE_NORMAL and ZONE_MOVABLE on node 1::
+With a kernel built with ``ZONE_DMA`` disabled and ``ZONE_DMA32`` enabled and
+booted with ``movablecore=80%`` parameter on an arm64 machine with 16 Gbytes of
+RAM equally split between two nodes, there will be ``ZONE_DMA32``,
+``ZONE_NORMAL`` and ``ZONE_MOVABLE`` on node 0, and ``ZONE_NORMAL`` and
+``ZONE_MOVABLE`` on node 1::


1G 9G 17G
@@ -116,7 +118,7 @@ Linux uses a node-local allocation policy to allocate memory from the node
closest to the running CPU. As processes tend to run on the same CPU, it is
likely the memory from the current node will be used. The allocation policy can
be controlled by users as described in
-`Documentation/admin-guide/mm/numa_memory_policy.rst`.
+Documentation/admin-guide/mm/numa_memory_policy.rst.

Most NUMA architectures maintain an array of pointers to the node
structures. The actual structures are allocated early during boot when
@@ -127,21 +129,21 @@ boot process by free_area_init() function, described later in Section


Along with the node structures, kernel maintains an array of ``nodemask_t``
-bitmasks called `node_states`. Each bitmask in this array represents a set of
-nodes with particular properties as defined by `enum node_states`:
+bitmasks called ``node_states``. Each bitmask in this array represents a set of
+nodes with particular properties as defined by ``enum node_states``:

-`N_POSSIBLE`
+``N_POSSIBLE``
The node could become online at some point.
-`N_ONLINE`
+``N_ONLINE``
The node is online.
-`N_NORMAL_MEMORY`
+``N_NORMAL_MEMORY``
The node has regular memory.
-`N_HIGH_MEMORY`
+``N_HIGH_MEMORY``
The node has regular or high memory. When ``CONFIG_HIGHMEM`` is disabled
- aliased to `N_NORMAL_MEMORY`.
-`N_MEMORY`
+ aliased to ``N_NORMAL_MEMORY``.
+``N_MEMORY``
The node has memory(regular, high, movable)
-`N_CPU`
+``N_CPU``
The node has one or more CPUs

For each node that has a property described above, the bit corresponding to the
@@ -160,7 +162,7 @@ For various operations possible with nodemasks please refer to
<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/nodemask.h>`_.

Among other things, nodemasks are used to provide macros for node traversal,
-namely `for_each_node()` and `for_each_online_node()`.
+namely ``for_each_node()`` and ``for_each_online_node()``.

For instance, to call a function foo() for each online node::

@@ -180,126 +182,130 @@ Here we briefly describe fields of this structure:
General
~~~~~~~

-`node_zones`
+``node_zones``
The zones for this node. Not all of the zones may be populated, but it is
the full list. It is referenced by this node's node_zonelists as well as
other node's node_zonelists.

-`node_zonelists` The list of all zones in all nodes. This list defines the
- order of zones that allocations are preferred from. The `node_zonelists` is
- set up by build_zonelists() in mm/page_alloc.c during the initialization of
+``node_zonelists``
+ The list of all zones in all nodes. This list defines the order of zones
+ that allocations are preferred from. The ``node_zonelists`` is set up by
+ ``build_zonelists()`` in ``mm/page_alloc.c`` during the initialization of
core memory management structures.

-`nr_zones`
+``nr_zones``
Number of populated zones in this node.

-`node_mem_map`
+``node_mem_map``
For UMA systems that use FLATMEM memory model the 0's node (and the only)
- `node_mem_map` is array of struct pages representing each physical frame.
+ ``node_mem_map`` is array of struct pages representing each physical frame.

-`node_page_ext`
+``node_page_ext``
For UMA systems that use FLATMEM memory model the 0's (and the only) node
- `node_mem_map` is array of extensions of struct pages. Available only in the
+ ``node_mem_map`` is array of extensions of struct pages. Available only in the
kernels built with ``CONFIG_PAGE_EXTENTION`` enabled.

-`node_start_pfn`
+``node_start_pfn``
The page frame number of the starting page frame in this node.

-`node_present_pages`
+``node_present_pages``
Total number of physical pages present in this node.

-`node_spanned_pages`
+``node_spanned_pages``
Total size of physical page range, including holes.

-`node_size_lock`
+``node_size_lock``
A lock that protects the fields defining the node extents. Only defined when
at least one of ``CONFIG_MEMORY_HOTPLUG`` or
``CONFIG_DEFERRED_STRUCT_PAGE_INIT`` configuration options are enabled.
+ ``pgdat_resize_lock()`` and ``pgdat_resize_unlock()`` are provided to
+ manipulate ``node_size_lock`` without checking for ``CONFIG_MEMORY_HOTPLUG``
+ or ``CONFIG_DEFERRED_STRUCT_PAGE_INIT``.

- pgdat_resize_lock() and pgdat_resize_unlock() are provided to manipulate
- node_size_lock without checking for CONFIG_MEMORY_HOTPLUG or
- CONFIG_DEFERRED_STRUCT_PAGE_INIT.
-
-`node_id`
+``node_id``
The Node ID (NID) of the node, starts at 0.

-`totalreserve_pages`
+``totalreserve_pages``
This is a per~node reserve of pages that are not available to userspace
allocations.

-`first_deferred_pfn`
+``first_deferred_pfn``
If memory initialization on large machines is deferred then this is the first
PFN that needs to be initialized. Defined only when
``CONFIG_DEFERRED_STRUCT_PAGE_INIT`` is enabled

-`deferred_split_queue`
+``deferred_split_queue``
Per-node queue of huge pages that their split was deferred. Defined only when ``CONFIG_TRANSPARENT_HUGEPAGE`` is enabled.

-`__lruvec`
- Per-node lruvec holding LRU lists and related parameters. Used only when memory cgroups are disabled. Should not be accessed directly, use mem_cgroup_lruvec() to look up lruvecs instead.
+``__lruvec``
+ Per-node lruvec holding LRU lists and related parameters. Used only when
+ memory cgroups are disabled. It should not be accessed directly, use
+ ``mem_cgroup_lruvec()`` to look up lruvecs instead.

Reclaim control
~~~~~~~~~~~~~~~

See also :ref:`Page Reclaim <page_reclaim>`.

-`kswapd`
+``kswapd``
Per-node instance of kswapd kernel thread.

-`kswapd_wait`, `pfmemalloc_wait`, `reclaim_wait`
+``kswapd_wait``, ``pfmemalloc_wait``, ``reclaim_wait``
Workqueues used to synchronize memory reclaim tasks

-`nr_writeback_throttled`
+``nr_writeback_throttled``
Number of tasks that are throttled waiting on dirty pages to clean.

-`nr_reclaim_start`
+``nr_reclaim_start``
Number of pages written while reclaim is throttled waiting for writeback.

-`kswapd_order`
+``kswapd_order``
Controls the order kswapd tries to reclaim

-`kswapd_highest_zoneidx`
+``kswapd_highest_zoneidx``
The highest zone index to be reclaimed by kswapd

-`kswapd_failures`
+``kswapd_failures``
Number of runs kswapd was unable to reclaim any pages

-`min_unmapped_pages`
- Minimal number of unmapped file backed pages that cannot be reclaimed. Determined by vm.min_unmapped_ratio sysctl.
- Only defined when ``CONFIG_NUMA`` is enabled.
+``min_unmapped_pages``
+ Minimal number of unmapped file backed pages that cannot be reclaimed.
+ Determined by ``vm.min_unmapped_ratio`` sysctl. Only defined when
+ ``CONFIG_NUMA`` is enabled.

-`min_slab_pages`
- Minimal number of SLAB pages that cannot be reclaimed. Determined by vm.min_slab_ratio sysctl.
- Only defined when ``CONFIG_NUMA`` is enabled
+``min_slab_pages``
+ Minimal number of SLAB pages that cannot be reclaimed. Determined by
+ ``vm.min_slab_ratio sysctl``. Only defined when ``CONFIG_NUMA`` is enabled

-`flags`
+``flags``
Flags controlling reclaim behavior.

Compaction control
~~~~~~~~~~~~~~~~~~

-`kcompactd_max_order`
+``kcompactd_max_order``
Page order that kcompactd should try to achieve.

-`kcompactd_highest_zoneidx`
+``kcompactd_highest_zoneidx``
The highest zone index to be compacted by kcompactd.

-`kcompactd_wait`
+``kcompactd_wait``
Workqueue used to synchronizes memory compaction tasks.

-`kcompactd`
+``kcompactd``
Per-node instance of kcompactd kernel thread.

-`proactive_compact_trigger`
- Determines if proactive compaction is enabled. Controlled by vm.compaction_proactiveness sysctl.
+``proactive_compact_trigger``
+ Determines if proactive compaction is enabled. Controlled by
+ ``vm.compaction_proactiveness`` sysctl.

Statistics
~~~~~~~~~~

-`per_cpu_nodestats`
+``per_cpu_nodestats``
Per-CPU VM statistics for the node

-`vm_stat`
+``vm_stat``
VM statistics for the node.

.. _zones:

> +For various operations possible with nodemasks please refer to
> +`include/linux/nodemask.h
> +<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/nodemask.h>`_.

Instead of linking to Linus's tree, just inline the source path:

---- >8 ----

diff --git a/Documentation/mm/physical_memory.rst b/Documentation/mm/physical_memory.rst
index 83e13166508a20..130880e5c369de 100644
--- a/Documentation/mm/physical_memory.rst
+++ b/Documentation/mm/physical_memory.rst
@@ -158,8 +158,7 @@ For example, for node 2 with normal memory and CPUs, bit 2 will be set in ::
node_states[N_CPU]

For various operations possible with nodemasks please refer to
-`include/linux/nodemask.h
-<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/nodemask.h>`_.
+``include/linux/nodemask.h``.

Among other things, nodemasks are used to provide macros for node traversal,
namely ``for_each_node()`` and ``for_each_online_node()``.
@@ -175,9 +174,8 @@ For instance, to call a function foo() for each online node::
Node structure
--------------

-The struct pglist_data is declared in `include/linux/mmzone.h
-<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/mmzone.h>`_.
-Here we briefly describe fields of this structure:
+The struct pglist_data is declared in ``include/linux/mmzone.h``. Here we
+briefly describe fields of this structure:

General
~~~~~~~

> +.. _zones:
> +
> +Zones
> +=====
> +
> +.. _pages:
> +
> +Pages
> +=====
> +
> +.. _folios:
> +
> +Folios
> +======
> +
> +.. _initialization:
> +
> +Initialization
> +==============

Are these sections stubs (no fields list for each types)? If so, add
admonitions to inform readers:

---- >8 ----

diff --git a/Documentation/mm/physical_memory.rst b/Documentation/mm/physical_memory.rst
index 130880e5c369de..cf61725d93b229 100644
--- a/Documentation/mm/physical_memory.rst
+++ b/Documentation/mm/physical_memory.rst
@@ -311,17 +311,33 @@ Statistics
Zones
=====

+.. admonition:: Stub
+
+ This section is incomplete. Please list and describe the appropriate fields.
+
.. _pages:

Pages
=====

+.. admonition:: Stub
+
+ This section is incomplete. Please list and describe the appropriate fields.
+
.. _folios:

Folios
======

+.. admonition:: Stub
+
+ This section is incomplete. Please list and describe the appropriate fields.
+
.. _initialization:

Initialization
==============
+
+.. admonition:: Stub
+
+ This section is incomplete. Please list and describe the appropriate fields.

Thanks.

--
An old man doll... just what I always wanted! - Clara

Attachment: signature.asc
Description: PGP signature