code:
.. SPDX-License-Identifier: GPL-2.0

===============
Detailed Usages
===============

DAMON provides below interfaces for different users.

- *DAMON user space tool.*
  `This <https://github.com/awslabs/damo>`_ is for privileged people such as
  system administrators who want a just-working human-friendly interface.
  Using this, users can use the DAMON’s major features in a human-friendly way.
  It may not be highly tuned for special cases, though.  It supports both
  virtual and physical address spaces monitoring.  For more detail, please
  refer to its `usage document
  <https://github.com/awslabs/damo/blob/next/USAGE.md>`_.
- *sysfs interface.*
  :ref:`This <sysfs_interface>` is for privileged user space programmers who
  want more optimized use of DAMON.  Using this, users can use DAMON’s major
  features by reading from and writing to special sysfs files.  Therefore,
  you can write and use your personalized DAMON sysfs wrapper programs that
  reads/writes the sysfs files instead of you.  The `DAMON user space tool
  <https://github.com/awslabs/damo>`_ is one example of such programs.  It
  supports both virtual and physical address spaces monitoring.  Note that this
  interface provides only simple :ref:`statistics <damos_stats>` for the
  monitoring results.  For detailed monitoring results, DAMON provides a
  :ref:`tracepoint <tracepoint>`.
- *debugfs interface.*
  :ref:`This <debugfs_interface>` is almost identical to :ref:`sysfs interface
  <sysfs_interface>`.  This will be removed after next LTS kernel is released,
  so users should move to the :ref:`sysfs interface <sysfs_interface>`.
- *Kernel Space Programming Interface.*
  :doc:`This </mm/damon/api>` is for kernel space programmers.  Using this,
  users can utilize every feature of DAMON most flexibly and efficiently by
  writing kernel space DAMON application programs for you.  You can even extend
  DAMON for various address spaces.  For detail, please refer to the interface
  :doc:`document </mm/damon/api>`.

.. _sysfs_interface:

sysfs Interface
===============

DAMON sysfs interface is built when ``CONFIG_DAMON_SYSFS`` is defined.  It
creates multiple directories and files under its sysfs directory,
``<sysfs>/kernel/mm/damon/``.  You can control DAMON by writing to and reading
from the files under the directory.

For a short example, users can monitor the virtual address space of a given
workload as below. ::

    # cd /sys/kernel/mm/damon/admin/
    # echo 1 > kdamonds/nr_kdamonds && echo 1 > kdamonds/0/contexts/nr_contexts
    # echo vaddr > kdamonds/0/contexts/0/operations
    # echo 1 > kdamonds/0/contexts/0/targets/nr_targets
    # echo $(pidof <workload>) > kdamonds/0/contexts/0/targets/0/pid_target
    # echo on > kdamonds/0/state

Files Hierarchy
---------------

The files hierarchy of DAMON sysfs interface is shown below.  In the below
figure, parents-children relations are represented with indentations, each
directory is having ``/`` suffix, and files in each directory are separated by
comma (","). ::

    /sys/kernel/mm/damon/admin
    │ kdamonds/nr_kdamonds
    │ │ 0/state,pid
    │ │ │ contexts/nr_contexts
    │ │ │ │ 0/avail_operations,operations
    │ │ │ │ │ monitoring_attrs/
    │ │ │ │ │ │ intervals/sample_us,aggr_us,update_us
    │ │ │ │ │ │ nr_regions/min,max
    │ │ │ │ │ targets/nr_targets
    │ │ │ │ │ │ 0/pid_target
    │ │ │ │ │ │ │ regions/nr_regions
    │ │ │ │ │ │ │ │ 0/start,end
    │ │ │ │ │ │ │ │ ...
    │ │ │ │ │ │ ...
    │ │ │ │ │ schemes/nr_schemes
    │ │ │ │ │ │ 0/action
    │ │ │ │ │ │ │ access_pattern/
    │ │ │ │ │ │ │ │ sz/min,max
    │ │ │ │ │ │ │ │ nr_accesses/min,max
    │ │ │ │ │ │ │ │ age/min,max
    │ │ │ │ │ │ │ quotas/ms,bytes,reset_interval_ms
    │ │ │ │ │ │ │ │ weights/sz_permil,nr_accesses_permil,age_permil
    │ │ │ │ │ │ │ watermarks/metric,interval_us,high,mid,low
    │ │ │ │ │ │ │ stats/nr_tried,sz_tried,nr_applied,sz_applied,qt_exceeds
    │ │ │ │ │ │ │ tried_regions/
    │ │ │ │ │ │ │ │ 0/start,end,nr_accesses,age
    │ │ │ │ │ │ │ │ ...
    │ │ │ │ │ │ ...
    │ │ │ │ ...
    │ │ ...

Root
----

The root of the DAMON sysfs interface is ``<sysfs>/kernel/mm/damon/``, and it
has one directory named ``admin``.  The directory contains the files for
privileged user space programs' control of DAMON.  User space tools or deamons
having the root permission could use this directory.

kdamonds/
---------

The monitoring-related information including request specifications and results
are called DAMON context.  DAMON executes each context with a kernel thread
called kdamond, and multiple kdamonds could run in parallel.

Under the ``admin`` directory, one directory, ``kdamonds``, which has files for
controlling the kdamonds exist.  In the beginning, this directory has only one
file, ``nr_kdamonds``.  Writing a number (``N``) to the file creates the number
of child directories named ``0`` to ``N-1``.  Each directory represents each
kdamond.

kdamonds/<N>/
-------------

In each kdamond directory, two files (``state`` and ``pid``) and one directory
(``contexts``) exist.

Reading ``state`` returns ``on`` if the kdamond is currently running, or
``off`` if it is not running.  Writing ``on`` or ``off`` makes the kdamond be
in the state.  Writing ``commit`` to the ``state`` file makes kdamond reads the
user inputs in the sysfs files except ``state`` file again.  Writing
``update_schemes_stats`` to ``state`` file updates the contents of stats files
for each DAMON-based operation scheme of the kdamond.  For details of the
stats, please refer to :ref:`stats section <sysfs_schemes_stats>`.  Writing
``update_schemes_tried_regions`` to ``state`` file updates the DAMON-based
operation scheme action tried regions directory for each DAMON-based operation
scheme of the kdamond.  Writing ``clear_schemes_tried_regions`` to ``state``
file clears the DAMON-based operating scheme action tried regions directory for
each DAMON-based operation scheme of the kdamond.  For details of the
DAMON-based operation scheme action tried regions directory, please refer to
:ref:tried_regions section <sysfs_schemes_tried_regions>`.

If the state is ``on``, reading ``pid`` shows the pid of the kdamond thread.

``contexts`` directory contains files for controlling the monitoring contexts
that this kdamond will execute.

kdamonds/<N>/contexts/
----------------------

In the beginning, this directory has only one file, ``nr_contexts``.  Writing a
number (``N``) to the file creates the number of child directories named as
``0`` to ``N-1``.  Each directory represents each monitoring context.  At the
moment, only one context per kdamond is supported, so only ``0`` or ``1`` can
be written to the file.

contexts/<N>/
-------------

In each context directory, two files (``avail_operations`` and ``operations``)
and three directories (``monitoring_attrs``, ``targets``, and ``schemes``)
exist.

DAMON supports multiple types of monitoring operations, including those for
virtual address space and the physical address space.  You can get the list of
available monitoring operations set on the currently running kernel by reading
``avail_operations`` file.  Based on the kernel configuration, the file will
list some or all of below keywords.

 - vaddr: Monitor virtual address spaces of specific processes
 - fvaddr: Monitor fixed virtual address ranges
 - paddr: Monitor the physical address space of the system

Please refer to :ref:`regions sysfs directory <sysfs_regions>` for detailed
differences between the operations sets in terms of the monitoring target
regions.

You can set and get what type of monitoring operations DAMON will use for the
context by writing one of the keywords listed in ``avail_operations`` file and
reading from the ``operations`` file.

.. _sysfs_monitoring_attrs:

contexts/<N>/monitoring_attrs/
------------------------------

Files for specifying attributes of the monitoring including required quality
and efficiency of the monitoring are in ``monitoring_attrs`` directory.
Specifically, two directories, ``intervals`` and ``nr_regions`` exist in this
directory.

Under ``intervals`` directory, three files for DAMON's sampling interval
(``sample_us``), aggregation interval (``aggr_us``), and update interval
(``update_us``) exist.  You can set and get the values in micro-seconds by
writing to and reading from the files.

Under ``nr_regions`` directory, two files for the lower-bound and upper-bound
of DAMON's monitoring regions (``min`` and ``max``, respectively), which
controls the monitoring overhead, exist.  You can set and get the values by
writing to and rading from the files.

For more details about the intervals and monitoring regions range, please refer
to the Design document (:doc:`/mm/damon/design`).

contexts/<N>/targets/
---------------------

In the beginning, this directory has only one file, ``nr_targets``.  Writing a
number (``N``) to the file creates the number of child directories named ``0``
to ``N-1``.  Each directory represents each monitoring target.

targets/<N>/
------------

In each target directory, one file (``pid_target``) and one directory
(``regions``) exist.

If you wrote ``vaddr`` to the ``contexts/<N>/operations``, each target should
be a process.  You can specify the process to DAMON by writing the pid of the
process to the ``pid_target`` file.

.. _sysfs_regions:

targets/<N>/regions
-------------------

When ``vaddr`` monitoring operations set is being used (``vaddr`` is written to
the ``contexts/<N>/operations`` file), DAMON automatically sets and updates the
monitoring target regions so that entire memory mappings of target processes
can be covered.  However, users could want to set the initial monitoring region
to specific address ranges.

In contrast, DAMON do not automatically sets and updates the monitoring target
regions when ``fvaddr`` or ``paddr`` monitoring operations sets are being used
(``fvaddr`` or ``paddr`` have written to the ``contexts/<N>/operations``).
Therefore, users should set the monitoring target regions by themselves in the
cases.

For such cases, users can explicitly set the initial monitoring target regions
as they want, by writing proper values to the files under this directory.

In the beginning, this directory has only one file, ``nr_regions``.  Writing a
number (``N``) to the file creates the number of child directories named ``0``
to ``N-1``.  Each directory represents each initial monitoring target region.

regions/<N>/
------------

In each region directory, you will find two files (``start`` and ``end``).  You
can set and get the start and end addresses of the initial monitoring target
region by writing to and reading from the files, respectively.

Each region should not overlap with others.  ``end`` of directory ``N`` should
be equal or smaller than ``start`` of directory ``N+1``.

contexts/<N>/schemes/
---------------------

For usual DAMON-based data access aware memory management optimizations, users
would normally want the system to apply a memory management action to a memory
region of a specific access pattern.  DAMON receives such formalized operation
schemes from the user and applies those to the target memory regions.  Users
can get and set the schemes by reading from and writing to files under this
directory.

In the beginning, this directory has only one file, ``nr_schemes``.  Writing a
number (``N``) to the file creates the number of child directories named ``0``
to ``N-1``.  Each directory represents each DAMON-based operation scheme.

schemes/<N>/
------------

In each scheme directory, five directories (``access_pattern``, ``quotas``,
``watermarks``, ``stats``, and ``tried_regions``) and one file (``action``)
exist.

The ``action`` file is for setting and getting what action you want to apply to
memory regions having specific access pattern of the interest.  The keywords
that can be written to and read from the file and their meaning are as below.

 - ``willneed``: Call ``madvise()`` for the region with ``MADV_WILLNEED``
 - ``cold``: Call ``madvise()`` for the region with ``MADV_COLD``
 - ``pageout``: Call ``madvise()`` for the region with ``MADV_PAGEOUT``
 - ``hugepage``: Call ``madvise()`` for the region with ``MADV_HUGEPAGE``
 - ``nohugepage``: Call ``madvise()`` for the region with ``MADV_NOHUGEPAGE``
 - ``lru_prio``: Prioritize the region on its LRU lists.
 - ``lru_deprio``: Deprioritize the region on its LRU lists.
 - ``stat``: Do nothing but count the statistics

schemes/<N>/access_pattern/
---------------------------

The target access pattern of each DAMON-based operation scheme is constructed
with three ranges including the size of the region in bytes, number of
monitored accesses per aggregate interval, and number of aggregated intervals
for the age of the region.

Under the ``access_pattern`` directory, three directories (``sz``,
``nr_accesses``, and ``age``) each having two files (``min`` and ``max``)
exist.  You can set and get the access pattern for the given scheme by writing
to and reading from the ``min`` and ``max`` files under ``sz``,
``nr_accesses``, and ``age`` directories, respectively.

schemes/<N>/quotas/
-------------------

Optimal ``target access pattern`` for each ``action`` is workload dependent, so
not easy to find.  Worse yet, setting a scheme of some action too aggressive
can cause severe overhead.  To avoid such overhead, users can limit time and
size quota for each scheme.  In detail, users can ask DAMON to try to use only
up to specific time (``time quota``) for applying the action, and to apply the
action to only up to specific amount (``size quota``) of memory regions having
the target access pattern within a given time interval (``reset interval``).

When the quota limit is expected to be exceeded, DAMON prioritizes found memory
regions of the ``target access pattern`` based on their size, access frequency,
and age.  For personalized prioritization, users can set the weights for the
three properties.

Under ``quotas`` directory, three files (``ms``, ``bytes``,
``reset_interval_ms``) and one directory (``weights``) having three files
(``sz_permil``, ``nr_accesses_permil``, and ``age_permil``) in it exist.

You can set the ``time quota`` in milliseconds, ``size quota`` in bytes, and
``reset interval`` in milliseconds by writing the values to the three files,
respectively.  You can also set the prioritization weights for size, access
frequency, and age in per-thousand unit by writing the values to the three
files under the ``weights`` directory.

schemes/<N>/watermarks/
-----------------------

To allow easy activation and deactivation of each scheme based on system
status, DAMON provides a feature called watermarks.  The feature receives five
values called ``metric``, ``interval``, ``high``, ``mid``, and ``low``.  The
``metric`` is the system metric such as free memory ratio that can be measured.
If the metric value of the system is higher than the value in ``high`` or lower
than ``low`` at the memoent, the scheme is deactivated.  If the value is lower
than ``mid``, the scheme is activated.

Under the watermarks directory, five files (``metric``, ``interval_us``,
``high``, ``mid``, and ``low``) for setting each value exist.  You can set and
get the five values by writing to the files, respectively.

Keywords and meanings of those that can be written to the ``metric`` file are
as below.

 - none: Ignore the watermarks
 - free_mem_rate: System's free memory rate (per thousand)

The ``interval`` should written in microseconds unit.

.. _sysfs_schemes_stats:

schemes/<N>/stats/
------------------

DAMON counts the total number and bytes of regions that each scheme is tried to
be applied, the two numbers for the regions that each scheme is successfully
applied, and the total number of the quota limit exceeds.  This statistics can
be used for online analysis or tuning of the schemes.

The statistics can be retrieved by reading the files under ``stats`` directory
(``nr_tried``, ``sz_tried``, ``nr_applied``, ``sz_applied``, and
``qt_exceeds``), respectively.  The files are not updated in real time, so you
should ask DAMON sysfs interface to updte the content of the files for the
stats by writing a special keyword, ``update_schemes_stats`` to the relevant
``kdamonds/<N>/state`` file.

.. _sysfs_schemes_tried_regions:

schemes/<N>/tried_regions/
--------------------------

When a special keyword, ``update_schemes_tried_regions``, is written to the
relevant ``kdamonds/<N>/state`` file, DAMON creates directories named integer
starting from ``0`` under this directory.  Each directory contains files
exposing detailed information about each of the memory region that the
corresponding scheme's ``action`` has tried to be applied under this directory,
during next :ref:`aggregation interval <sysfs_monitoring_attrs>`.  The
information includes address range, ``nr_accesses``, , and ``age`` of the
region.

The directories will be removed when another special keyword,
``clear_schemes_tried_regions``, is written to the relevant
``kdamonds/<N>/state`` file.

tried_regions/<N>/
------------------

In each region directory, you will find four files (``start``, ``end``,
``nr_accesses``, and ``age``).  Reading the files will show the start and end
addresses, ``nr_accesses``, and ``age`` of the region that corresponding
DAMON-based operation scheme ``action`` has tried to be applied.

Example
~~~~~~~

Below commands applies a scheme saying "If a memory region of size in [4KiB,
8KiB] is showing accesses per aggregate interval in [0, 5] for aggregate
interval in [10, 20], page out the region.  For the paging out, use only up to
10ms per second, and also don't page out more than 1GiB per second.  Under the
limitation, page out memory regions having longer age first.  Also, check the
free memory rate of the system every 5 seconds, start the monitoring and paging
out when the free memory rate becomes lower than 50%, but stop it if the free
memory rate becomes larger than 60%, or lower than 30%". ::

    # cd <sysfs>/kernel/mm/damon/admin
    # # populate directories
    # echo 1 > kdamonds/nr_kdamonds; echo 1 > kdamonds/0/contexts/nr_contexts;
    # echo 1 > kdamonds/0/contexts/0/schemes/nr_schemes
    # cd kdamonds/0/contexts/0/schemes/0
    # # set the basic access pattern and the action
    # echo 4096 > access_pattern/sz/min
    # echo 8192 > access_pattern/sz/max
    # echo 0 > access_pattern/nr_accesses/min
    # echo 5 > access_pattern/nr_accesses/max
    # echo 10 > access_pattern/age/min
    # echo 20 > access_pattern/age/max
    # echo pageout > action
    # # set quotas
    # echo 10 > quotas/ms
    # echo $((1024*1024*1024)) > quotas/bytes
    # echo 1000 > quotas/reset_interval_ms
    # # set watermark
    # echo free_mem_rate > watermarks/metric
    # echo 5000000 > watermarks/interval_us
    # echo 600 > watermarks/high
    # echo 500 > watermarks/mid
    # echo 300 > watermarks/low

Please note that it's highly recommended to use user space tools like `damo
<https://github.com/awslabs/damo>`_ rather than manually reading and writing
the files as above.  Above is only for an example.

.. _debugfs_interface:

debugfs Interface
=================

.. note::

  DAMON debugfs interface will be removed after next LTS kernel is released, so
  users should move to the :ref:`sysfs interface <sysfs_interface>`.

DAMON exports eight files, ``attrs``, ``target_ids``, ``init_regions``,
``schemes``, ``monitor_on``, ``kdamond_pid``, ``mk_contexts`` and
``rm_contexts`` under its debugfs directory, ``<debugfs>/damon/``.

Attributes
----------

Users can get and set the ``sampling interval``, ``aggregation interval``,
``update interval``, and min/max number of monitoring target regions by
reading from and writing to the ``attrs`` file.  To know about the monitoring
attributes in detail, please refer to the :doc:`/mm/damon/design`.  For
example, below commands set those values to 5 ms, 100 ms, 1,000 ms, 10 and
1000, and then check it again::

    # cd <debugfs>/damon
    # echo 5000 100000 1000000 10 1000 > attrs
    # cat attrs
    5000 100000 1000000 10 1000

Target IDs
----------

Some types of address spaces supports multiple monitoring target.  For example,
the virtual memory address spaces monitoring can have multiple processes as the
monitoring targets.  Users can set the targets by writing relevant id values of
the targets to, and get the ids of the current targets by reading from the
``target_ids`` file.  In case of the virtual address spaces monitoring, the
values should be pids of the monitoring target processes.  For example, below
commands set processes having pids 42 and 4242 as the monitoring targets and
check it again::

    # cd <debugfs>/damon
    # echo 42 4242 > target_ids
    # cat target_ids
    42 4242

Users can also monitor the physical memory address space of the system by
writing a special keyword, "``paddr\n``" to the file.  Because physical address
space monitoring doesn't support multiple targets, reading the file will show a
fake value, ``42``, as below::

    # cd <debugfs>/damon
    # echo paddr > target_ids
    # cat target_ids
    42

Note that setting the target ids doesn't start the monitoring.

Initial Monitoring Target Regions
---------------------------------

In case of the virtual address space monitoring, DAMON automatically sets and
updates the monitoring target regions so that entire memory mappings of target
processes can be covered.  However, users can want to limit the monitoring
region to specific address ranges, such as the heap, the stack, or specific
file-mapped area.  Or, some users can know the initial access pattern of their
workloads and therefore want to set optimal initial regions for the 'adaptive
regions adjustment'.

In contrast, DAMON do not automatically sets and updates the monitoring target
regions in case of physical memory monitoring.  Therefore, users should set the
monitoring target regions by themselves.

In such cases, users can explicitly set the initial monitoring target regions
as they want, by writing proper values to the ``init_regions`` file.  The input
should be a sequence of three integers separated by white spaces that represent
one region in below form.::

    <target idx> <start address> <end address>

The ``target idx`` should be the index of the target in ``target_ids`` file,
starting from ``0``, and the regions should be passed in address order.  For
example, below commands will set a couple of address ranges, ``1-100`` and
``100-200`` as the initial monitoring target region of pid 42, which is the
first one (index ``0``) in ``target_ids``, and another couple of address
ranges, ``20-40`` and ``50-100`` as that of pid 4242, which is the second one
(index ``1``) in ``target_ids``.::

    # cd <debugfs>/damon
    # cat target_ids
    42 4242
    # echo "0   1       100 \
            0   100     200 \
            1   20      40  \
            1   50      100" > init_regions

Note that this sets the initial monitoring target regions only.  In case of
virtual memory monitoring, DAMON will automatically updates the boundary of the
regions after one ``update interval``.  Therefore, users should set the
``update interval`` large enough in this case, if they don't want the
update.

Schemes
-------

For usual DAMON-based data access aware memory management optimizations, users
would simply want the system to apply a memory management action to a memory
region of a specific access pattern.  DAMON receives such formalized operation
schemes from the user and applies those to the target processes.

Users can get and set the schemes by reading from and writing to ``schemes``
debugfs file.  Reading the file also shows the statistics of each scheme.  To
the file, each of the schemes should be represented in each line in below
form::

    <target access pattern> <action> <quota> <watermarks>

You can disable schemes by simply writing an empty string to the file.

Target Access Pattern
~~~~~~~~~~~~~~~~~~~~~

The ``<target access pattern>`` is constructed with three ranges in below
form::

    min-size max-size min-acc max-acc min-age max-age

Specifically, bytes for the size of regions (``min-size`` and ``max-size``),
number of monitored accesses per aggregate interval for access frequency
(``min-acc`` and ``max-acc``), number of aggregate intervals for the age of
regions (``min-age`` and ``max-age``) are specified.  Note that the ranges are
closed interval.

Action
~~~~~~

The ``<action>`` is a predefined integer for memory management actions, which
DAMON will apply to the regions having the target access pattern.  The
supported numbers and their meanings are as below.

 - 0: Call ``madvise()`` for the region with ``MADV_WILLNEED``
 - 1: Call ``madvise()`` for the region with ``MADV_COLD``
 - 2: Call ``madvise()`` for the region with ``MADV_PAGEOUT``
 - 3: Call ``madvise()`` for the region with ``MADV_HUGEPAGE``
 - 4: Call ``madvise()`` for the region with ``MADV_NOHUGEPAGE``
 - 5: Do nothing but count the statistics

Quota
~~~~~

Optimal ``target access pattern`` for each ``action`` is workload dependent, so
not easy to find.  Worse yet, setting a scheme of some action too aggressive
can cause severe overhead.  To avoid such overhead, users can limit time and
size quota for the scheme via the ``<quota>`` in below form::

    <ms> <sz> <reset interval> <priority weights>

This makes DAMON to try to use only up to ``<ms>`` milliseconds for applying
the action to memory regions of the ``target access pattern`` within the
``<reset interval>`` milliseconds, and to apply the action to only up to
``<sz>`` bytes of memory regions within the ``<reset interval>``.  Setting both
``<ms>`` and ``<sz>`` zero disables the quota limits.

When the quota limit is expected to be exceeded, DAMON prioritizes found memory
regions of the ``target access pattern`` based on their size, access frequency,
and age.  For personalized prioritization, users can set the weights for the
three properties in ``<priority weights>`` in below form::

    <size weight> <access frequency weight> <age weight>

Watermarks
~~~~~~~~~~

Some schemes would need to run based on current value of the system's specific
metrics like free memory ratio.  For such cases, users can specify watermarks
for the condition.::

    <metric> <check interval> <high mark> <middle mark> <low mark>

``<metric>`` is a predefined integer for the metric to be checked.  The
supported numbers and their meanings are as below.

 - 0: Ignore the watermarks
 - 1: System's free memory rate (per thousand)

The value of the metric is checked every ``<check interval>`` microseconds.

If the value is higher than ``<high mark>`` or lower than ``<low mark>``, the
scheme is deactivated.  If the value is lower than ``<mid mark>``, the scheme
is activated.

.. _damos_stats:

Statistics
~~~~~~~~~~

It also counts the total number and bytes of regions that each scheme is tried
to be applied, the two numbers for the regions that each scheme is successfully
applied, and the total number of the quota limit exceeds.  This statistics can
be used for online analysis or tuning of the schemes.

The statistics can be shown by reading the ``schemes`` file.  Reading the file
will show each scheme you entered in each line, and the five numbers for the
statistics will be added at the end of each line.

Example
~~~~~~~

Below commands applies a scheme saying "If a memory region of size in [4KiB,
8KiB] is showing accesses per aggregate interval in [0, 5] for aggregate
interval in [10, 20], page out the region.  For the paging out, use only up to
10ms per second, and also don't page out more than 1GiB per second.  Under the
limitation, page out memory regions having longer age first.  Also, check the
free memory rate of the system every 5 seconds, start the monitoring and paging
out when the free memory rate becomes lower than 50%, but stop it if the free
memory rate becomes larger than 60%, or lower than 30%".::

    # cd <debugfs>/damon
    # scheme="4096 8192  0 5    10 20    2"  # target access pattern and action
    # scheme+=" 10 $((1024*1024*1024)) 1000" # quotas
    # scheme+=" 0 0 100"                     # prioritization weights
    # scheme+=" 1 5000000 600 500 300"       # watermarks
    # echo "$scheme" > schemes

Turning On/Off
--------------

Setting the files as described above doesn't incur effect unless you explicitly
start the monitoring.  You can start, stop, and check the current status of the
monitoring by writing to and reading from the ``monitor_on`` file.  Writing
``on`` to the file starts the monitoring of the targets with the attributes.
Writing ``off`` to the file stops those.  DAMON also stops if every target
process is terminated.  Below example commands turn on, off, and check the
status of DAMON::

    # cd <debugfs>/damon
    # echo on > monitor_on
    # echo off > monitor_on
    # cat monitor_on
    off

Please note that you cannot write to the above-mentioned debugfs files while
the monitoring is turned on.  If you write to the files while DAMON is running,
an error code such as ``-EBUSY`` will be returned.

Monitoring Thread PID
---------------------

DAMON does requested monitoring with a kernel thread called ``kdamond``.  You
can get the pid of the thread by reading the ``kdamond_pid`` file.  When the
monitoring is turned off, reading the file returns ``none``. ::

    # cd <debugfs>/damon
    # cat monitor_on
    off
    # cat kdamond_pid
    none
    # echo on > monitor_on
    # cat kdamond_pid
    18594

Using Multiple Monitoring Threads
---------------------------------

One ``kdamond`` thread is created for each monitoring context.  You can create
and remove monitoring contexts for multiple ``kdamond`` required use case using
the ``mk_contexts`` and ``rm_contexts`` files.

Writing the name of the new context to the ``mk_contexts`` file creates a
directory of the name on the DAMON debugfs directory.  The directory will have
DAMON debugfs files for the context. ::

    # cd <debugfs>/damon
    # ls foo
    # ls: cannot access 'foo': No such file or directory
    # echo foo > mk_contexts
    # ls foo
    # attrs  init_regions  kdamond_pid  schemes  target_ids

If the context is not needed anymore, you can remove it and the corresponding
directory by putting the name of the context to the ``rm_contexts`` file. ::

    # echo foo > rm_contexts
    # ls foo
    # ls: cannot access 'foo': No such file or directory

Note that ``mk_contexts``, ``rm_contexts``, and ``monitor_on`` files are in the
root directory only.

.. _tracepoint:

Tracepoint for Monitoring Results
=================================

DAMON provides the monitoring results via a tracepoint,
``damon:damon_aggregated``.  While the monitoring is turned on, you could
record the tracepoint events and show results using tracepoint supporting tools
like ``perf``.  For example::

    # echo on > monitor_on
    # perf record -e damon:damon_aggregated &
    # sleep 5
    # kill 9 $(pidof perf)
    # echo off > monitor_on
    # perf script


code:
.. _hugetlbpage:

=============
HugeTLB Pages
=============

Overview
========

The intent of this file is to give a brief summary of hugetlbpage support in
the Linux kernel.  This support is built on top of multiple page size support
that is provided by most modern architectures.  For example, x86 CPUs normally
support 4K and 2M (1G if architecturally supported) page sizes, ia64
architecture supports multiple page sizes 4K, 8K, 64K, 256K, 1M, 4M, 16M,
256M and ppc64 supports 4K and 16M.  A TLB is a cache of virtual-to-physical
translations.  Typically this is a very scarce resource on processor.
Operating systems try to make best use of limited number of TLB resources.
This optimization is more critical now as bigger and bigger physical memories
(several GBs) are more readily available.

Users can use the huge page support in Linux kernel by either using the mmap
system call or standard SYSV shared memory system calls (shmget, shmat).

First the Linux kernel needs to be built with the CONFIG_HUGETLBFS
(present under "File systems") and CONFIG_HUGETLB_PAGE (selected
automatically when CONFIG_HUGETLBFS is selected) configuration
options.

The ``/proc/meminfo`` file provides information about the total number of
persistent hugetlb pages in the kernel's huge page pool.  It also displays
default huge page size and information about the number of free, reserved
and surplus huge pages in the pool of huge pages of default size.
The huge page size is needed for generating the proper alignment and
size of the arguments to system calls that map huge page regions.

The output of ``cat /proc/meminfo`` will include lines like::

	HugePages_Total: uuu
	HugePages_Free:  vvv
	HugePages_Rsvd:  www
	HugePages_Surp:  xxx
	Hugepagesize:    yyy kB
	Hugetlb:         zzz kB

where:

HugePages_Total
	is the size of the pool of huge pages.
HugePages_Free
	is the number of huge pages in the pool that are not yet
        allocated.
HugePages_Rsvd
	is short for "reserved," and is the number of huge pages for
        which a commitment to allocate from the pool has been made,
        but no allocation has yet been made.  Reserved huge pages
        guarantee that an application will be able to allocate a
        huge page from the pool of huge pages at fault time.
HugePages_Surp
	is short for "surplus," and is the number of huge pages in
        the pool above the value in ``/proc/sys/vm/nr_hugepages``. The
        maximum number of surplus huge pages is controlled by
        ``/proc/sys/vm/nr_overcommit_hugepages``.
	Note: When the feature of freeing unused vmemmap pages associated
	with each hugetlb page is enabled, the number of surplus huge pages
	may be temporarily larger than the maximum number of surplus huge
	pages when the system is under memory pressure.
Hugepagesize
	is the default hugepage size (in kB).
Hugetlb
        is the total amount of memory (in kB), consumed by huge
        pages of all sizes.
        If huge pages of different sizes are in use, this number
        will exceed HugePages_Total \* Hugepagesize. To get more
        detailed information, please, refer to
        ``/sys/kernel/mm/hugepages`` (described below).

``/proc/filesystems`` should also show a filesystem of type "hugetlbfs"
configured in the kernel.

``/proc/sys/vm/nr_hugepages`` indicates the current number of "persistent" huge
pages in the kernel's huge page pool.  "Persistent" huge pages will be
returned to the huge page pool when freed by a task.  A user with root
privileges can dynamically allocate more or free some persistent huge pages
by increasing or decreasing the value of ``nr_hugepages``.

Note: When the feature of freeing unused vmemmap pages associated with each
hugetlb page is enabled, we can fail to free the huge pages triggered by
the user when ths system is under memory pressure.  Please try again later.

Pages that are used as huge pages are reserved inside the kernel and cannot
be used for other purposes.  Huge pages cannot be swapped out under
memory pressure.

Once a number of huge pages have been pre-allocated to the kernel huge page
pool, a user with appropriate privilege can use either the mmap system call
or shared memory system calls to use the huge pages.  See the discussion of
:ref:`Using Huge Pages <using_huge_pages>`, below.

The administrator can allocate persistent huge pages on the kernel boot
command line by specifying the "hugepages=N" parameter, where 'N' = the
number of huge pages requested.  This is the most reliable method of
allocating huge pages as memory has not yet become fragmented.

Some platforms support multiple huge page sizes.  To allocate huge pages
of a specific size, one must precede the huge pages boot command parameters
with a huge page size selection parameter "hugepagesz=<size>".  <size> must
be specified in bytes with optional scale suffix [kKmMgG].  The default huge
page size may be selected with the "default_hugepagesz=<size>" boot parameter.

Hugetlb boot command line parameter semantics

hugepagesz
	Specify a huge page size.  Used in conjunction with hugepages
	parameter to preallocate a number of huge pages of the specified
	size.  Hence, hugepagesz and hugepages are typically specified in
	pairs such as::

		hugepagesz=2M hugepages=512

	hugepagesz can only be specified once on the command line for a
	specific huge page size.  Valid huge page sizes are architecture
	dependent.
hugepages
	Specify the number of huge pages to preallocate.  This typically
	follows a valid hugepagesz or default_hugepagesz parameter.  However,
	if hugepages is the first or only hugetlb command line parameter it
	implicitly specifies the number of huge pages of default size to
	allocate.  If the number of huge pages of default size is implicitly
	specified, it can not be overwritten by a hugepagesz,hugepages
	parameter pair for the default size.  This parameter also has a
	node format.  The node format specifies the number of huge pages
	to allocate on specific nodes.

	For example, on an architecture with 2M default huge page size::

		hugepages=256 hugepagesz=2M hugepages=512

	will result in 256 2M huge pages being allocated and a warning message
	indicating that the hugepages=512 parameter is ignored.  If a hugepages
	parameter is preceded by an invalid hugepagesz parameter, it will
	be ignored.

	Node format example::

		hugepagesz=2M hugepages=0:1,1:2

	It will allocate 1 2M hugepage on node0 and 2 2M hugepages on node1.
	If the node number is invalid,  the parameter will be ignored.

default_hugepagesz
	Specify the default huge page size.  This parameter can
	only be specified once on the command line.  default_hugepagesz can
	optionally be followed by the hugepages parameter to preallocate a
	specific number of huge pages of default size.  The number of default
	sized huge pages to preallocate can also be implicitly specified as
	mentioned in the hugepages section above.  Therefore, on an
	architecture with 2M default huge page size::

		hugepages=256
		default_hugepagesz=2M hugepages=256
		hugepages=256 default_hugepagesz=2M

	will all result in 256 2M huge pages being allocated.  Valid default
	huge page size is architecture dependent.
hugetlb_free_vmemmap
	When CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP is set, this enables HugeTLB
	Vmemmap Optimization (HVO).

When multiple huge page sizes are supported, ``/proc/sys/vm/nr_hugepages``
indicates the current number of pre-allocated huge pages of the default size.
Thus, one can use the following command to dynamically allocate/deallocate
default sized persistent huge pages::

	echo 20 > /proc/sys/vm/nr_hugepages

This command will try to adjust the number of default sized huge pages in the
huge page pool to 20, allocating or freeing huge pages, as required.

On a NUMA platform, the kernel will attempt to distribute the huge page pool
over all the set of allowed nodes specified by the NUMA memory policy of the
task that modifies ``nr_hugepages``. The default for the allowed nodes--when the
task has default memory policy--is all on-line nodes with memory.  Allowed
nodes with insufficient available, contiguous memory for a huge page will be
silently skipped when allocating persistent huge pages.  See the
:ref:`discussion below <mem_policy_and_hp_alloc>`
of the interaction of task memory policy, cpusets and per node attributes
with the allocation and freeing of persistent huge pages.

The success or failure of huge page allocation depends on the amount of
physically contiguous memory that is present in system at the time of the
allocation attempt.  If the kernel is unable to allocate huge pages from
some nodes in a NUMA system, it will attempt to make up the difference by
allocating extra pages on other nodes with sufficient available contiguous
memory, if any.

System administrators may want to put this command in one of the local rc
init files.  This will enable the kernel to allocate huge pages early in
the boot process when the possibility of getting physical contiguous pages
is still very high.  Administrators can verify the number of huge pages
actually allocated by checking the sysctl or meminfo.  To check the per node
distribution of huge pages in a NUMA system, use::

	cat /sys/devices/system/node/node*/meminfo | fgrep Huge

``/proc/sys/vm/nr_overcommit_hugepages`` specifies how large the pool of
huge pages can grow, if more huge pages than ``/proc/sys/vm/nr_hugepages`` are
requested by applications.  Writing any non-zero value into this file
indicates that the hugetlb subsystem is allowed to try to obtain that
number of "surplus" huge pages from the kernel's normal page pool, when the
persistent huge page pool is exhausted. As these surplus huge pages become
unused, they are freed back to the kernel's normal page pool.

When increasing the huge page pool size via ``nr_hugepages``, any existing
surplus pages will first be promoted to persistent huge pages.  Then, additional
huge pages will be allocated, if necessary and if possible, to fulfill
the new persistent huge page pool size.

The administrator may shrink the pool of persistent huge pages for
the default huge page size by setting the ``nr_hugepages`` sysctl to a
smaller value.  The kernel will attempt to balance the freeing of huge pages
across all nodes in the memory policy of the task modifying ``nr_hugepages``.
Any free huge pages on the selected nodes will be freed back to the kernel's
normal page pool.

Caveat: Shrinking the persistent huge page pool via ``nr_hugepages`` such that
it becomes less than the number of huge pages in use will convert the balance
of the in-use huge pages to surplus huge pages.  This will occur even if
the number of surplus pages would exceed the overcommit value.  As long as
this condition holds--that is, until ``nr_hugepages+nr_overcommit_hugepages`` is
increased sufficiently, or the surplus huge pages go out of use and are freed--
no more surplus huge pages will be allowed to be allocated.

With support for multiple huge page pools at run-time available, much of
the huge page userspace interface in ``/proc/sys/vm`` has been duplicated in
sysfs.
The ``/proc`` interfaces discussed above have been retained for backwards
compatibility. The root huge page control directory in sysfs is::

	/sys/kernel/mm/hugepages

For each huge page size supported by the running kernel, a subdirectory
will exist, of the form::

	hugepages-${size}kB

Inside each of these directories, the set of files contained in ``/proc``
will exist.  In addition, two additional interfaces for demoting huge
pages may exist::

        demote
        demote_size
	nr_hugepages
	nr_hugepages_mempolicy
	nr_overcommit_hugepages
	free_hugepages
	resv_hugepages
	surplus_hugepages

The demote interfaces provide the ability to split a huge page into
smaller huge pages.  For example, the x86 architecture supports both
1GB and 2MB huge pages sizes.  A 1GB huge page can be split into 512
2MB huge pages.  Demote interfaces are not available for the smallest
huge page size.  The demote interfaces are:

demote_size
        is the size of demoted pages.  When a page is demoted a corresponding
        number of huge pages of demote_size will be created.  By default,
        demote_size is set to the next smaller huge page size.  If there are
        multiple smaller huge page sizes, demote_size can be set to any of
        these smaller sizes.  Only huge page sizes less than the current huge
        pages size are allowed.

demote
        is used to demote a number of huge pages.  A user with root privileges
        can write to this file.  It may not be possible to demote the
        requested number of huge pages.  To determine how many pages were
        actually demoted, compare the value of nr_hugepages before and after
        writing to the demote interface.  demote is a write only interface.

The interfaces which are the same as in ``/proc`` (all except demote and
demote_size) function as described above for the default huge page-sized case.

.. _mem_policy_and_hp_alloc:

Interaction of Task Memory Policy with Huge Page Allocation/Freeing
===================================================================

Whether huge pages are allocated and freed via the ``/proc`` interface or
the ``/sysfs`` interface using the ``nr_hugepages_mempolicy`` attribute, the
NUMA nodes from which huge pages are allocated or freed are controlled by the
NUMA memory policy of the task that modifies the ``nr_hugepages_mempolicy``
sysctl or attribute.  When the ``nr_hugepages`` attribute is used, mempolicy
is ignored.

The recommended method to allocate or free huge pages to/from the kernel
huge page pool, using the ``nr_hugepages`` example above, is::

    numactl --interleave <node-list> echo 20 \
				>/proc/sys/vm/nr_hugepages_mempolicy

or, more succinctly::

    numactl -m <node-list> echo 20 >/proc/sys/vm/nr_hugepages_mempolicy

This will allocate or free ``abs(20 - nr_hugepages)`` to or from the nodes
specified in <node-list>, depending on whether number of persistent huge pages
is initially less than or greater than 20, respectively.  No huge pages will be
allocated nor freed on any node not included in the specified <node-list>.

When adjusting the persistent hugepage count via ``nr_hugepages_mempolicy``, any
memory policy mode--bind, preferred, local or interleave--may be used.  The
resulting effect on persistent huge page allocation is as follows:

#. Regardless of mempolicy mode [see
   :ref:`Documentation/admin-guide/mm/numa_memory_policy.rst <numa_memory_policy>`],
   persistent huge pages will be distributed across the node or nodes
   specified in the mempolicy as if "interleave" had been specified.
   However, if a node in the policy does not contain sufficient contiguous
   memory for a huge page, the allocation will not "fallback" to the nearest
   neighbor node with sufficient contiguous memory.  To do this would cause
   undesirable imbalance in the distribution of the huge page pool, or
   possibly, allocation of persistent huge pages on nodes not allowed by
   the task's memory policy.

#. One or more nodes may be specified with the bind or interleave policy.
   If more than one node is specified with the preferred policy, only the
   lowest numeric id will be used.  Local policy will select the node where
   the task is running at the time the nodes_allowed mask is constructed.
   For local policy to be deterministic, the task must be bound to a cpu or
   cpus in a single node.  Otherwise, the task could be migrated to some
   other node at any time after launch and the resulting node will be
   indeterminate.  Thus, local policy is not very useful for this purpose.
   Any of the other mempolicy modes may be used to specify a single node.

#. The nodes allowed mask will be derived from any non-default task mempolicy,
   whether this policy was set explicitly by the task itself or one of its
   ancestors, such as numactl.  This means that if the task is invoked from a
   shell with non-default policy, that policy will be used.  One can specify a
   node list of "all" with numactl --interleave or --membind [-m] to achieve
   interleaving over all nodes in the system or cpuset.

#. Any task mempolicy specified--e.g., using numactl--will be constrained by
   the resource limits of any cpuset in which the task runs.  Thus, there will
   be no way for a task with non-default policy running in a cpuset with a
   subset of the system nodes to allocate huge pages outside the cpuset
   without first moving to a cpuset that contains all of the desired nodes.

#. Boot-time huge page allocation attempts to distribute the requested number
   of huge pages over all on-lines nodes with memory.

Per Node Hugepages Attributes
=============================

A subset of the contents of the root huge page control directory in sysfs,
described above, will be replicated under each the system device of each
NUMA node with memory in::

	/sys/devices/system/node/node[0-9]*/hugepages/

Under this directory, the subdirectory for each supported huge page size
contains the following attribute files::

	nr_hugepages
	free_hugepages
	surplus_hugepages

The free\_' and surplus\_' attribute files are read-only.  They return the number
of free and surplus [overcommitted] huge pages, respectively, on the parent
node.

The ``nr_hugepages`` attribute returns the total number of huge pages on the
specified node.  When this attribute is written, the number of persistent huge
pages on the parent node will be adjusted to the specified value, if sufficient
resources exist, regardless of the task's mempolicy or cpuset constraints.

Note that the number of overcommit and reserve pages remain global quantities,
as we don't know until fault time, when the faulting task's mempolicy is
applied, from which node the huge page allocation will be attempted.

.. _using_huge_pages:

Using Huge Pages
================

If the user applications are going to request huge pages using mmap system
call, then it is required that system administrator mount a file system of
type hugetlbfs::

  mount -t hugetlbfs \
	-o uid=<value>,gid=<value>,mode=<value>,pagesize=<value>,size=<value>,\
	min_size=<value>,nr_inodes=<value> none /mnt/huge

This command mounts a (pseudo) filesystem of type hugetlbfs on the directory
``/mnt/huge``.  Any file created on ``/mnt/huge`` uses huge pages.

The ``uid`` and ``gid`` options sets the owner and group of the root of the
file system.  By default the ``uid`` and ``gid`` of the current process
are taken.

The ``mode`` option sets the mode of root of file system to value & 01777.
This value is given in octal. By default the value 0755 is picked.

If the platform supports multiple huge page sizes, the ``pagesize`` option can
be used to specify the huge page size and associated pool. ``pagesize``
is specified in bytes. If ``pagesize`` is not specified the platform's
default huge page size and associated pool will be used.

The ``size`` option sets the maximum value of memory (huge pages) allowed
for that filesystem (``/mnt/huge``). The ``size`` option can be specified
in bytes, or as a percentage of the specified huge page pool (``nr_hugepages``).
The size is rounded down to HPAGE_SIZE boundary.

The ``min_size`` option sets the minimum value of memory (huge pages) allowed
for the filesystem. ``min_size`` can be specified in the same way as ``size``,
either bytes or a percentage of the huge page pool.
At mount time, the number of huge pages specified by ``min_size`` are reserved
for use by the filesystem.
If there are not enough free huge pages available, the mount will fail.
As huge pages are allocated to the filesystem and freed, the reserve count
is adjusted so that the sum of allocated and reserved huge pages is always
at least ``min_size``.

The option ``nr_inodes`` sets the maximum number of inodes that ``/mnt/huge``
can use.

If the ``size``, ``min_size`` or ``nr_inodes`` option is not provided on
command line then no limits are set.

For ``pagesize``, ``size``, ``min_size`` and ``nr_inodes`` options, you can
use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo.
For example, size=2K has the same meaning as size=2048.

While read system calls are supported on files that reside on hugetlb
file systems, write system calls are not.

Regular chown, chgrp, and chmod commands (with right permissions) could be
used to change the file attributes on hugetlbfs.

Also, it is important to note that no such mount command is required if
applications are going to use only shmat/shmget system calls or mmap with
MAP_HUGETLB.  For an example of how to use mmap with MAP_HUGETLB see
:ref:`map_hugetlb <map_hugetlb>` below.

Users who wish to use hugetlb memory via shared memory segment should be
members of a supplementary group and system admin needs to configure that gid
into ``/proc/sys/vm/hugetlb_shm_group``.  It is possible for same or different
applications to use any combination of mmaps and shm* calls, though the mount of
filesystem will be required for using mmap calls without MAP_HUGETLB.

Syscalls that operate on memory backed by hugetlb pages only have their lengths
aligned to the native page size of the processor; they will normally fail with
errno set to EINVAL or exclude hugetlb pages that extend beyond the length if
not hugepage aligned.  For example, munmap(2) will fail if memory is backed by
a hugetlb page and the length is smaller than the hugepage size.

Examples
========

.. _map_hugetlb:

``map_hugetlb``
	see tools/testing/selftests/vm/map_hugetlb.c

``hugepage-shm``
	see tools/testing/selftests/vm/hugepage-shm.c

``hugepage-mmap``
	see tools/testing/selftests/vm/hugepage-mmap.c

The `libhugetlbfs`_  library provides a wide range of userspace tools
to help with huge page usability, environment setup, and control.

.. _libhugetlbfs: https://github.com/libhugetlbfs/libhugetlbfs

repo_name: angery/linux


code:
.. _idle_page_tracking:

==================
Idle Page Tracking
==================

Motivation
==========

The idle page tracking feature allows to track which memory pages are being
accessed by a workload and which are idle. This information can be useful for
estimating the workload's working set size, which, in turn, can be taken into
account when configuring the workload parameters, setting memory cgroup limits,
or deciding where to place the workload within a compute cluster.

It is enabled by CONFIG_IDLE_PAGE_TRACKING=y.

.. _user_api:

User API
========

The idle page tracking API is located at ``/sys/kernel/mm/page_idle``.
Currently, it consists of the only read-write file,
``/sys/kernel/mm/page_idle/bitmap``.

The file implements a bitmap where each bit corresponds to a memory page. The
bitmap is represented by an array of 8-byte integers, and the page at PFN #i is
mapped to bit #i%64 of array element #i/64, byte order is native. When a bit is
set, the corresponding page is idle.

A page is considered idle if it has not been accessed since it was marked idle
(for more details on what "accessed" actually means see the :ref:`Implementation
Details <impl_details>` section).
To mark a page idle one has to set the bit corresponding to
the page by writing to the file. A value written to the file is OR-ed with the
current bitmap value.

Only accesses to user memory pages are tracked. These are pages mapped to a
process address space, page cache and buffer pages, swap cache pages. For other
page types (e.g. SLAB pages) an attempt to mark a page idle is silently ignored,
and hence such pages are never reported idle.

For huge pages the idle flag is set only on the head page, so one has to read
``/proc/kpageflags`` in order to correctly count idle huge pages.

Reading from or writing to ``/sys/kernel/mm/page_idle/bitmap`` will return
-EINVAL if you are not starting the read/write on an 8-byte boundary, or
if the size of the read/write is not a multiple of 8 bytes. Writing to
this file beyond max PFN will return -ENXIO.

That said, in order to estimate the amount of pages that are not used by a
workload one should:

 1. Mark all the workload's pages as idle by setting corresponding bits in
    ``/sys/kernel/mm/page_idle/bitmap``. The pages can be found by reading
    ``/proc/pid/pagemap`` if the workload is represented by a process, or by
    filtering out alien pages using ``/proc/kpagecgroup`` in case the workload
    is placed in a memory cgroup.

 2. Wait until the workload accesses its working set.

 3. Read ``/sys/kernel/mm/page_idle/bitmap`` and count the number of bits set.
    If one wants to ignore certain types of pages, e.g. mlocked pages since they
    are not reclaimable, he or she can filter them out using
    ``/proc/kpageflags``.

The page-types tool in the tools/vm directory can be used to assist in this.
If the tool is run initially with the appropriate option, it will mark all the
queried pages as idle.  Subsequent runs of the tool can then show which pages have
their idle flag cleared in the interim.

See :ref:`Documentation/admin-guide/mm/pagemap.rst <pagemap>` for more
information about ``/proc/pid/pagemap``, ``/proc/kpageflags``, and
``/proc/kpagecgroup``.

.. _impl_details:

Implementation Details
======================

The kernel internally keeps track of accesses to user memory pages in order to
reclaim unreferenced pages first on memory shortage conditions. A page is
considered referenced if it has been recently accessed via a process address
space, in which case one or more PTEs it is mapped to will have the Accessed bit
set, or marked accessed explicitly by the kernel (see mark_page_accessed()). The
latter happens when:

 - a userspace process reads or writes a page using a system call (e.g. read(2)
   or write(2))

 - a page that is used for storing filesystem buffers is read or written,
   because a process needs filesystem metadata stored in it (e.g. lists a
   directory tree)

 - a page is accessed by a device driver using get_user_pages()

When a dirty page is written to swap or disk as a result of memory reclaim or
exceeding the dirty memory limit, it is not marked referenced.

The idle memory tracking feature adds a new page flag, the Idle flag. This flag
is set manually, by writing to ``/sys/kernel/mm/page_idle/bitmap`` (see the
:ref:`User API <user_api>`
section), and cleared automatically whenever a page is referenced as defined
above.

When a page is marked idle, the Accessed bit must be cleared in all PTEs it is
mapped to, otherwise we will not be able to detect accesses to the page coming
from a process address space. To avoid interference with the reclaimer, which,
as noted above, uses the Accessed bit to promote actively referenced pages, one
more page flag is introduced, the Young flag. When the PTE Accessed bit is
cleared as a result of setting or updating a page's Idle flag, the Young flag
is set on the page. The reclaimer treats the Young flag as an extra PTE
Accessed bit and therefore will consider such a page as referenced.

Since the idle memory tracking feature is based on the memory reclaimer logic,
it only works with pages that are on an LRU list, other pages are silently
ignored. That means it will ignore a user memory page if it is isolated, but
since there are usually not many of them, it should not affect the overall
result noticeably. In order not to stall scanning of the idle page bitmap,
locked pages may be skipped too.


code:
=================
Memory Management
=================

Linux memory management subsystem is responsible, as the name implies,
for managing the memory in the system. This includes implementation of
virtual memory and demand paging, memory allocation both for kernel
internal structures and user space programs, mapping of files into
processes address space and many other cool things.

Linux memory management is a complex system with many configurable
settings. Most of these settings are available via ``/proc``
filesystem and can be quired and adjusted using ``sysctl``. These APIs
are described in Documentation/admin-guide/sysctl/vm.rst and in `man 5 proc`_.

.. _man 5 proc: http://man7.org/linux/man-pages/man5/proc.5.html

Linux memory management has its own jargon and if you are not yet
familiar with it, consider reading
:ref:`Documentation/admin-guide/mm/concepts.rst <mm_concepts>`.

Here we document in detail how to interact with various mechanisms in
the Linux memory management.

.. toctree::
   :maxdepth: 1

   concepts
   cma_debugfs
   damon/index
   hugetlbpage
   idle_page_tracking
   ksm
   memory-hotplug
   multigen_lru
   nommu-mmap
   numa_memory_policy
   numaperf
   pagemap
   shrinker_debugfs
   soft-dirty
   swap_numa
   transhuge
   userfaultfd
   zswap


code:
.. _admin_guide_ksm:

=======================
Kernel Samepage Merging
=======================

Overview
========

KSM is a memory-saving de-duplication feature, enabled by CONFIG_KSM=y,
added to the Linux kernel in 2.6.32.  See ``mm/ksm.c`` for its implementation,
and http://lwn.net/Articles/306704/ and https://lwn.net/Articles/330589/

KSM was originally developed for use with KVM (where it was known as
Kernel Shared Memory), to fit more virtual machines into physical memory,
by sharing the data common between them.  But it can be useful to any
application which generates many instances of the same data.

The KSM daemon ksmd periodically scans those areas of user memory
which have been registered with it, looking for pages of identical
content which can be replaced by a single write-protected page (which
is automatically copied if a process later wants to update its
content). The amount of pages that KSM daemon scans in a single pass
and the time between the passes are configured using :ref:`sysfs
intraface <ksm_sysfs>`

KSM only merges anonymous (private) pages, never pagecache (file) pages.
KSM's merged pages were originally locked into kernel memory, but can now
be swapped out just like other user pages (but sharing is broken when they
are swapped back in: ksmd must rediscover their identity and merge again).

Controlling KSM with madvise
============================

KSM only operates on those areas of address space which an application
has advised to be likely candidates for merging, by using the madvise(2)
system call::

	int madvise(addr, length, MADV_MERGEABLE)

The app may call

::

	int madvise(addr, length, MADV_UNMERGEABLE)

to cancel that advice and restore unshared pages: whereupon KSM
unmerges whatever it merged in that range.  Note: this unmerging call
may suddenly require more memory than is available - possibly failing
with EAGAIN, but more probably arousing the Out-Of-Memory killer.

If KSM is not configured into the running kernel, madvise MADV_MERGEABLE
and MADV_UNMERGEABLE simply fail with EINVAL.  If the running kernel was
built with CONFIG_KSM=y, those calls will normally succeed: even if the
KSM daemon is not currently running, MADV_MERGEABLE still registers
the range for whenever the KSM daemon is started; even if the range
cannot contain any pages which KSM could actually merge; even if
MADV_UNMERGEABLE is applied to a range which was never MADV_MERGEABLE.

If a region of memory must be split into at least one new MADV_MERGEABLE
or MADV_UNMERGEABLE region, the madvise may return ENOMEM if the process
will exceed ``vm.max_map_count`` (see Documentation/admin-guide/sysctl/vm.rst).

Like other madvise calls, they are intended for use on mapped areas of
the user address space: they will report ENOMEM if the specified range
includes unmapped gaps (though working on the intervening mapped areas),
and might fail with EAGAIN if not enough memory for internal structures.

Applications should be considerate in their use of MADV_MERGEABLE,
restricting its use to areas likely to benefit.  KSM's scans may use a lot
of processing power: some installations will disable KSM for that reason.

.. _ksm_sysfs:

KSM daemon sysfs interface
==========================

The KSM daemon is controlled by sysfs files in ``/sys/kernel/mm/ksm/``,
readable by all but writable only by root:

pages_to_scan
        how many pages to scan before ksmd goes to sleep
        e.g. ``echo 100 > /sys/kernel/mm/ksm/pages_to_scan``.

        Default: 100 (chosen for demonstration purposes)

sleep_millisecs
        how many milliseconds ksmd should sleep before next scan
        e.g. ``echo 20 > /sys/kernel/mm/ksm/sleep_millisecs``

        Default: 20 (chosen for demonstration purposes)

merge_across_nodes
        specifies if pages from different NUMA nodes can be merged.
        When set to 0, ksm merges only pages which physically reside
        in the memory area of same NUMA node. That brings lower
        latency to access of shared pages. Systems with more nodes, at
        significant NUMA distances, are likely to benefit from the
        lower latency of setting 0. Smaller systems, which need to
        minimize memory usage, are likely to benefit from the greater
        sharing of setting 1 (default). You may wish to compare how
        your system performs under each setting, before deciding on
        which to use. ``merge_across_nodes`` setting can be changed only
        when there are no ksm shared pages in the system: set run 2 to
        unmerge pages first, then to 1 after changing
        ``merge_across_nodes``, to remerge according to the new setting.

        Default: 1 (merging across nodes as in earlier releases)

run
        * set to 0 to stop ksmd from running but keep merged pages,
        * set to 1 to run ksmd e.g. ``echo 1 > /sys/kernel/mm/ksm/run``,
        * set to 2 to stop ksmd and unmerge all pages currently merged, but
	  leave mergeable areas registered for next run.

        Default: 0 (must be changed to 1 to activate KSM, except if
        CONFIG_SYSFS is disabled)

use_zero_pages
        specifies whether empty pages (i.e. allocated pages that only
        contain zeroes) should be treated specially.  When set to 1,
        empty pages are merged with the kernel zero page(s) instead of
        with each other as it would happen normally. This can improve
        the performance on architectures with coloured zero pages,
        depending on the workload. Care should be taken when enabling
        this setting, as it can potentially degrade the performance of
        KSM for some workloads, for example if the checksums of pages
        candidate for merging match the checksum of an empty
        page. This setting can be changed at any time, it is only
        effective for pages merged after the change.

        Default: 0 (normal KSM behaviour as in earlier releases)

max_page_sharing
        Maximum sharing allowed for each KSM page. This enforces a
        deduplication limit to avoid high latency for virtual memory
        operations that involve traversal of the virtual mappings that
        share the KSM page. The minimum value is 2 as a newly created
        KSM page will have at least two sharers. The higher this value
        the faster KSM will merge the memory and the higher the
        deduplication factor will be, but the slower the worst case
        virtual mappings traversal could be for any given KSM
        page. Slowing down this traversal means there will be higher
        latency for certain virtual memory operations happening during
        swapping, compaction, NUMA balancing and page migration, in
        turn decreasing responsiveness for the caller of those virtual
        memory operations. The scheduler latency of other tasks not
        involved with the VM operations doing the virtual mappings
        traversal is not affected by this parameter as these
        traversals are always schedule friendly themselves.

stable_node_chains_prune_millisecs
        specifies how frequently KSM checks the metadata of the pages
        that hit the deduplication limit for stale information.
        Smaller milllisecs values will free up the KSM metadata with
        lower latency, but they will make ksmd use more CPU during the
        scan. It's a noop if not a single KSM page hit the
        ``max_page_sharing`` yet.

The effectiveness of KSM and MADV_MERGEABLE is shown in ``/sys/kernel/mm/ksm/``:

pages_shared
        how many shared pages are being used
pages_sharing
        how many more sites are sharing them i.e. how much saved
pages_unshared
        how many pages unique but repeatedly checked for merging
pages_volatile
        how many pages changing too fast to be placed in a tree
full_scans
        how many times all mergeable areas have been scanned
stable_node_chains
        the number of KSM pages that hit the ``max_page_sharing`` limit
stable_node_dups
        number of duplicated KSM pages

A high ratio of ``pages_sharing`` to ``pages_shared`` indicates good
sharing, but a high ratio of ``pages_unshared`` to ``pages_sharing``
indicates wasted effort.  ``pages_volatile`` embraces several
different kinds of activity, but a high proportion there would also
indicate poor use of madvise MADV_MERGEABLE.

The maximum possible ``pages_sharing/pages_shared`` ratio is limited by the
``max_page_sharing`` tunable. To increase the ratio ``max_page_sharing`` must
be increased accordingly.

Monitoring KSM profit
=====================

KSM can save memory by merging identical pages, but also can consume
additional memory, because it needs to generate a number of rmap_items to
save each scanned page's brief rmap information. Some of these pages may
be merged, but some may not be abled to be merged after being checked
several times, which are unprofitable memory consumed.

1) How to determine whether KSM save memory or consume memory in system-wide
   range? Here is a simple approximate calculation for reference::

	general_profit =~ pages_sharing * sizeof(page) - (all_rmap_items) *
			  sizeof(rmap_item);

   where all_rmap_items can be easily obtained by summing ``pages_sharing``,
   ``pages_shared``, ``pages_unshared`` and ``pages_volatile``.

2) The KSM profit inner a single process can be similarly obtained by the
   following approximate calculation::

	process_profit =~ ksm_merging_pages * sizeof(page) -
			  ksm_rmap_items * sizeof(rmap_item).

   where ksm_merging_pages is shown under the directory ``/proc/<pid>/``,
   and ksm_rmap_items is shown in ``/proc/<pid>/ksm_stat``.

From the perspective of application, a high ratio of ``ksm_rmap_items`` to
``ksm_merging_pages`` means a bad madvise-applied policy, so developers or
administrators have to rethink how to change madvise policy. Giving an example
for reference, a page's size is usually 4K, and the rmap_item's size is
separately 32B on 32-bit CPU architecture and 64B on 64-bit CPU architecture.
so if the ``ksm_rmap_items/ksm_merging_pages`` ratio exceeds 64 on 64-bit CPU
or exceeds 128 on 32-bit CPU, then the app's madvise policy should be dropped,
because the ksm profit is approximately zero or negative.

Monitoring KSM events
=====================

There are some counters in /proc/vmstat that may be used to monitor KSM events.
KSM might help save memory, it's a tradeoff by may suffering delay on KSM COW
or on swapping in copy. Those events could help users evaluate whether or how
to use KSM. For example, if cow_ksm increases too fast, user may decrease the
range of madvise(, , MADV_MERGEABLE).

cow_ksm
	is incremented every time a KSM page triggers copy on write (COW)
	when users try to write to a KSM page, we have to make a copy.

ksm_swpin_copy
	is incremented every time a KSM page is copied when swapping in
	note that KSM page might be copied when swapping in because do_swap_page()
	cannot do all the locking needed to reconstitute a cross-anon_vma KSM page.

--
Izik Eidus,
Hugh Dickins, 17 Nov 2009


code:
.. _admin_guide_memory_hotplug:

==================
Memory Hot(Un)Plug
==================

This document describes generic Linux support for memory hot(un)plug with
a focus on System RAM, including ZONE_MOVABLE support.

.. contents:: :local:

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

Memory hot(un)plug allows for increasing and decreasing the size of physical
memory available to a machine at runtime. In the simplest case, it consists of
physically plugging or unplugging a DIMM at runtime, coordinated with the
operating system.

Memory hot(un)plug is used for various purposes:

- The physical memory available to a machine can be adjusted at runtime, up- or
  downgrading the memory capacity. This dynamic memory resizing, sometimes
  referred to as "capacity on demand", is frequently used with virtual machines
  and logical partitions.

- Replacing hardware, such as DIMMs or whole NUMA nodes, without downtime. One
  example is replacing failing memory modules.

- Reducing energy consumption either by physically unplugging memory modules or
  by logically unplugging (parts of) memory modules from Linux.

Further, the basic memory hot(un)plug infrastructure in Linux is nowadays also
used to expose persistent memory, other performance-differentiated memory and
reserved memory regions as ordinary system RAM to Linux.

Linux only supports memory hot(un)plug on selected 64 bit architectures, such as
x86_64, arm64, ppc64, s390x and ia64.

Memory Hot(Un)Plug Granularity
------------------------------

Memory hot(un)plug in Linux uses the SPARSEMEM memory model, which divides the
physical memory address space into chunks of the same size: memory sections. The
size of a memory section is architecture dependent. For example, x86_64 uses
128 MiB and ppc64 uses 16 MiB.

Memory sections are combined into chunks referred to as "memory blocks". The
size of a memory block is architecture dependent and corresponds to the smallest
granularity that can be hot(un)plugged. The default size of a memory block is
the same as memory section size, unless an architecture specifies otherwise.

All memory blocks have the same size.

Phases of Memory Hotplug
------------------------

Memory hotplug consists of two phases:

(1) Adding the memory to Linux
(2) Onlining memory blocks

In the first phase, metadata, such as the memory map ("memmap") and page tables
for the direct mapping, is allocated and initialized, and memory blocks are
created; the latter also creates sysfs files for managing newly created memory
blocks.

In the second phase, added memory is exposed to the page allocator. After this
phase, the memory is visible in memory statistics, such as free and total
memory, of the system.

Phases of Memory Hotunplug
--------------------------

Memory hotunplug consists of two phases:

(1) Offlining memory blocks
(2) Removing the memory from Linux

In the fist phase, memory is "hidden" from the page allocator again, for
example, by migrating busy memory to other memory locations and removing all
relevant free pages from the page allocator After this phase, the memory is no
longer visible in memory statistics of the system.

In the second phase, the memory blocks are removed and metadata is freed.

Memory Hotplug Notifications
============================

There are various ways how Linux is notified about memory hotplug events such
that it can start adding hotplugged memory. This description is limited to
systems that support ACPI; mechanisms specific to other firmware interfaces or
virtual machines are not described.

ACPI Notifications
------------------

Platforms that support ACPI, such as x86_64, can support memory hotplug
notifications via ACPI.

In general, a firmware supporting memory hotplug defines a memory class object
HID "PNP0C80". When notified about hotplug of a new memory device, the ACPI
driver will hotplug the memory to Linux.

If the firmware supports hotplug of NUMA nodes, it defines an object _HID
"ACPI0004", "PNP0A05", or "PNP0A06". When notified about an hotplug event, all
assigned memory devices are added to Linux by the ACPI driver.

Similarly, Linux can be notified about requests to hotunplug a memory device or
a NUMA node via ACPI. The ACPI driver will try offlining all relevant memory
blocks, and, if successful, hotunplug the memory from Linux.

Manual Probing
--------------

On some architectures, the firmware may not be able to notify the operating
system about a memory hotplug event. Instead, the memory has to be manually
probed from user space.

The probe interface is located at::

	/sys/devices/system/memory/probe

Only complete memory blocks can be probed. Individual memory blocks are probed
by providing the physical start address of the memory block::

	% echo addr > /sys/devices/system/memory/probe

Which results in a memory block for the range [addr, addr + memory_block_size)
being created.

.. note::

  Using the probe interface is discouraged as it is easy to crash the kernel,
  because Linux cannot validate user input; this interface might be removed in
  the future.

Onlining and Offlining Memory Blocks
====================================

After a memory block has been created, Linux has to be instructed to actually
make use of that memory: the memory block has to be "online".

Before a memory block can be removed, Linux has to stop using any memory part of
the memory block: the memory block has to be "offlined".

The Linux kernel can be configured to automatically online added memory blocks
and drivers automatically trigger offlining of memory blocks when trying
hotunplug of memory. Memory blocks can only be removed once offlining succeeded
and drivers may trigger offlining of memory blocks when attempting hotunplug of
memory.

Onlining Memory Blocks Manually
-------------------------------

If auto-onlining of memory blocks isn't enabled, user-space has to manually
trigger onlining of memory blocks. Often, udev rules are used to automate this
task in user space.

Onlining of a memory block can be triggered via::

	% echo online > /sys/devices/system/memory/memoryXXX/state

Or alternatively::

	% echo 1 > /sys/devices/system/memory/memoryXXX/online

The kernel will select the target zone automatically, depending on the
configured ``online_policy``.

One can explicitly request to associate an offline memory block with
ZONE_MOVABLE by::

	% echo online_movable > /sys/devices/system/memory/memoryXXX/state

Or one can explicitly request a kernel zone (usually ZONE_NORMAL) by::

	% echo online_kernel > /sys/devices/system/memory/memoryXXX/state

In any case, if onlining succeeds, the state of the memory block is changed to
be "online". If it fails, the state of the memory block will remain unchanged
and the above commands will fail.

Onlining Memory Blocks Automatically
------------------------------------

The kernel can be configured to try auto-onlining of newly added memory blocks.
If this feature is disabled, the memory blocks will stay offline until
explicitly onlined from user space.

The configured auto-online behavior can be observed via::

	% cat /sys/devices/system/memory/auto_online_blocks

Auto-onlining can be enabled by writing ``online``, ``online_kernel`` or
``online_movable`` to that file, like::

	% echo online > /sys/devices/system/memory/auto_online_blocks

Similarly to manual onlining, with ``online`` the kernel will select the
target zone automatically, depending on the configured ``online_policy``.

Modifying the auto-online behavior will only affect all subsequently added
memory blocks only.

.. note::

  In corner cases, auto-onlining can fail. The kernel won't retry. Note that
  auto-onlining is not expected to fail in default configurations.

.. note::

  DLPAR on ppc64 ignores the ``offline`` setting and will still online added
  memory blocks; if onlining fails, memory blocks are removed again.

Offlining Memory Blocks
-----------------------

In the current implementation, Linux's memory offlining will try migrating all
movable pages off the affected memory block. As most kernel allocations, such as
page tables, are unmovable, page migration can fail and, therefore, inhibit
memory offlining from succeeding.

Having the memory provided by memory block managed by ZONE_MOVABLE significantly
increases memory offlining reliability; still, memory offlining can fail in
some corner cases.

Further, memory offlining might retry for a long time (or even forever), until
aborted by the user.

Offlining of a memory block can be triggered via::

	% echo offline > /sys/devices/system/memory/memoryXXX/state

Or alternatively::

	% echo 0 > /sys/devices/system/memory/memoryXXX/online

If offlining succeeds, the state of the memory block is changed to be "offline".
If it fails, the state of the memory block will remain unchanged and the above
commands will fail, for example, via::

	bash: echo: write error: Device or resource busy

or via::

	bash: echo: write error: Invalid argument

Observing the State of Memory Blocks
------------------------------------

The state (online/offline/going-offline) of a memory block can be observed
either via::

	% cat /sys/device/system/memory/memoryXXX/state

Or alternatively (1/0) via::

	% cat /sys/device/system/memory/memoryXXX/online

For an online memory block, the managing zone can be observed via::

	% cat /sys/device/system/memory/memoryXXX/valid_zones

Configuring Memory Hot(Un)Plug
==============================

There are various ways how system administrators can configure memory
hot(un)plug and interact with memory blocks, especially, to online them.

Memory Hot(Un)Plug Configuration via Sysfs
------------------------------------------

Some memory hot(un)plug properties can be configured or inspected via sysfs in::

	/sys/devices/system/memory/

The following files are currently defined:

====================== =========================================================
``auto_online_blocks`` read-write: set or get the default state of new memory
		       blocks; configure auto-onlining.

		       The default value depends on the
		       CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE kernel configuration
		       option.

		       See the ``state`` property of memory blocks for details.
``block_size_bytes``   read-only: the size in bytes of a memory block.
``probe``	       write-only: add (probe) selected memory blocks manually
		       from user space by supplying the physical start address.

		       Availability depends on the CONFIG_ARCH_MEMORY_PROBE
		       kernel configuration option.
``uevent``	       read-write: generic udev file for device subsystems.
====================== =========================================================

.. note::

  When the CONFIG_MEMORY_FAILURE kernel configuration option is enabled, two
  additional files ``hard_offline_page`` and ``soft_offline_page`` are available
  to trigger hwpoisoning of pages, for example, for testing purposes. Note that
  this functionality is not really related to memory hot(un)plug or actual
  offlining of memory blocks.

Memory Block Configuration via Sysfs
------------------------------------

Each memory block is represented as a memory block device that can be
onlined or offlined. All memory blocks have their device information located in
sysfs. Each present memory block is listed under
``/sys/devices/system/memory`` as::

	/sys/devices/system/memory/memoryXXX

where XXX is the memory block id; the number of digits is variable.

A present memory block indicates that some memory in the range is present;
however, a memory block might span memory holes. A memory block spanning memory
holes cannot be offlined.

For example, assume 1 GiB memory block size. A device for a memory starting at
0x100000000 is ``/sys/device/system/memory/memory4``::

	(0x100000000 / 1Gib = 4)

This device covers address range [0x100000000 ... 0x140000000)

The following files are currently defined:

=================== ============================================================
``online``	    read-write: simplified interface to trigger onlining /
		    offlining and to observe the state of a memory block.
		    When onlining, the zone is selected automatically.
``phys_device``	    read-only: legacy interface only ever used on s390x to
		    expose the covered storage increment.
``phys_index``	    read-only: the memory block id (XXX).
``removable``	    read-only: legacy interface that indicated whether a memory
		    block was likely to be offlineable or not. Nowadays, the
		    kernel return ``1`` if and only if it supports memory
		    offlining.
``state``	    read-write: advanced interface to trigger onlining /
		    offlining and to observe the state of a memory block.

		    When writing, ``online``, ``offline``, ``online_kernel`` and
		    ``online_movable`` are supported.

		    ``online_movable`` specifies onlining to ZONE_MOVABLE.
		    ``online_kernel`` specifies onlining to the default kernel
		    zone for the memory block, such as ZONE_NORMAL.
                    ``online`` let's the kernel select the zone automatically.

		    When reading, ``online``, ``offline`` and ``going-offline``
		    may be returned.
``uevent``	    read-write: generic uevent file for devices.
``valid_zones``     read-only: when a block is online, shows the zone it
		    belongs to; when a block is offline, shows what zone will
		    manage it when the block will be onlined.

		    For online memory blocks, ``DMA``, ``DMA32``, ``Normal``,
		    ``Movable`` and ``none`` may be returned. ``none`` indicates
		    that memory provided by a memory block is managed by
		    multiple zones or spans multiple nodes; such memory blocks
		    cannot be offlined. ``Movable`` indicates ZONE_MOVABLE.
		    Other values indicate a kernel zone.

		    For offline memory blocks, the first column shows the
		    zone the kernel would select when onlining the memory block
		    right now without further specifying a zone.

		    Availability depends on the CONFIG_MEMORY_HOTREMOVE
		    kernel configuration option.
=================== ============================================================

.. note::

  If the CONFIG_NUMA kernel configuration option is enabled, the memoryXXX/
  directories can also be accessed via symbolic links located in the
  ``/sys/devices/system/node/node*`` directories.

  For example::

	/sys/devices/system/node/node0/memory9 -> ../../memory/memory9

  A backlink will also be created::

	/sys/devices/system/memory/memory9/node0 -> ../../node/node0

Command Line Parameters
-----------------------

Some command line parameters affect memory hot(un)plug handling. The following
command line parameters are relevant:

======================== =======================================================
``memhp_default_state``	 configure auto-onlining by essentially setting
                         ``/sys/devices/system/memory/auto_online_blocks``.
``movable_node``	 configure automatic zone selection in the kernel when
			 using the ``contig-zones`` online policy. When
			 set, the kernel will default to ZONE_MOVABLE when
			 onlining a memory block, unless other zones can be kept
			 contiguous.
======================== =======================================================

See Documentation/admin-guide/kernel-parameters.txt for a more generic
description of these command line parameters.

Module Parameters
------------------

Instead of additional command line parameters or sysfs files, the
``memory_hotplug`` subsystem now provides a dedicated namespace for module
parameters. Module parameters can be set via the command line by predicating
them with ``memory_hotplug.`` such as::

	memory_hotplug.memmap_on_memory=1

and they can be observed (and some even modified at runtime) via::

	/sys/module/memory_hotplug/parameters/

The following module parameters are currently defined:

================================ ===============================================
``memmap_on_memory``		 read-write: Allocate memory for the memmap from
				 the added memory block itself. Even if enabled,
				 actual support depends on various other system
				 properties and should only be regarded as a
				 hint whether the behavior would be desired.

				 While allocating the memmap from the memory
				 block itself makes memory hotplug less likely
				 to fail and keeps the memmap on the same NUMA
				 node in any case, it can fragment physical
				 memory in a way that huge pages in bigger
				 granularity cannot be formed on hotplugged
				 memory.
``online_policy``		 read-write: Set the basic policy used for
				 automatic zone selection when onlining memory
				 blocks without specifying a target zone.
				 ``contig-zones`` has been the kernel default
				 before this parameter was added. After an
				 online policy was configured and memory was
				 online, the policy should not be changed
				 anymore.

				 When set to ``contig-zones``, the kernel will
				 try keeping zones contiguous. If a memory block
				 intersects multiple zones or no zone, the
				 behavior depends on the ``movable_node`` kernel
				 command line parameter: default to ZONE_MOVABLE
				 if set, default to the applicable kernel zone
				 (usually ZONE_NORMAL) if not set.

				 When set to ``auto-movable``, the kernel will
				 try onlining memory blocks to ZONE_MOVABLE if
				 possible according to the configuration and
				 memory device details. With this policy, one
				 can avoid zone imbalances when eventually
				 hotplugging a lot of memory later and still
				 wanting to be able to hotunplug as much as
				 possible reliably, very desirable in
				 virtualized environments. This policy ignores
				 the ``movable_node`` kernel command line
				 parameter and isn't really applicable in
				 environments that require it (e.g., bare metal
				 with hotunpluggable nodes) where hotplugged
				 memory might be exposed via the
				 firmware-provided memory map early during boot
				 to the system instead of getting detected,
				 added and onlined  later during boot (such as
				 done by virtio-mem or by some hypervisors
				 implementing emulated DIMMs). As one example, a
				 hotplugged DIMM will be onlined either
				 completely to ZONE_MOVABLE or completely to
				 ZONE_NORMAL, not a mixture.
				 As another example, as many memory blocks
				 belonging to a virtio-mem device will be
				 onlined to ZONE_MOVABLE as possible,
				 special-casing units of memory blocks that can
				 only get hotunplugged together. *This policy
				 does not protect from setups that are
				 problematic with ZONE_MOVABLE and does not
				 change the zone of memory blocks dynamically
				 after they were onlined.*
``auto_movable_ratio``		 read-write: Set the maximum MOVABLE:KERNEL
				 memory ratio in % for the ``auto-movable``
				 online policy. Whether the ratio applies only
				 for the system across all NUMA nodes or also
				 per NUMA nodes depends on the
				 ``auto_movable_numa_aware`` configuration.

				 All accounting is based on present memory pages
				 in the zones combined with accounting per
				 memory device. Memory dedicated to the CMA
				 allocator is accounted as MOVABLE, although
				 residing on one of the kernel zones. The
				 possible ratio depends on the actual workload.
				 The kernel default is "301" %, for example,
				 allowing for hotplugging 24 GiB to a 8 GiB VM
				 and automatically onlining all hotplugged
				 memory to ZONE_MOVABLE in many setups. The
				 additional 1% deals with some pages being not
				 present, for example, because of some firmware
				 allocations.

				 Note that ZONE_NORMAL memory provided by one
				 memory device does not allow for more
				 ZONE_MOVABLE memory for a different memory
				 device. As one example, onlining memory of a
				 hotplugged DIMM to ZONE_NORMAL will not allow
				 for another hotplugged DIMM to get onlined to
				 ZONE_MOVABLE automatically. In contrast, memory
				 hotplugged by a virtio-mem device that got
				 onlined to ZONE_NORMAL will allow for more
				 ZONE_MOVABLE memory within *the same*
				 virtio-mem device.
``auto_movable_numa_aware``	 read-write: Configure whether the
				 ``auto_movable_ratio`` in the ``auto-movable``
				 online policy also applies per NUMA
				 node in addition to the whole system across all
				 NUMA nodes. The kernel default is "Y".

				 Disabling NUMA awareness can be helpful when
				 dealing with NUMA nodes that should be
				 completely hotunpluggable, onlining the memory
				 completely to ZONE_MOVABLE automatically if
				 possible.

				 Parameter availability depends on CONFIG_NUMA.
================================ ===============================================

ZONE_MOVABLE
============

ZONE_MOVABLE is an important mechanism for more reliable memory offlining.
Further, having system RAM managed by ZONE_MOVABLE instead of one of the
kernel zones can increase the number of possible transparent huge pages and
dynamically allocated huge pages.

Most kernel allocations are unmovable. Important examples include the memory
map (usually 1/64ths of memory), page tables, and kmalloc(). Such allocations
can only be served from the kernel zones.

Most user space pages, such as anonymous memory, and page cache pages are
movable. Such allocations can be served from ZONE_MOVABLE and the kernel zones.

Only movable allocations are served from ZONE_MOVABLE, resulting in unmovable
allocations being limited to the kernel zones. Without ZONE_MOVABLE, there is
absolutely no guarantee whether a memory block can be offlined successfully.

Zone Imbalances
---------------

Having too much system RAM managed by ZONE_MOVABLE is called a zone imbalance,
which can harm the system or degrade performance. As one example, the kernel
might crash because it runs out of free memory for unmovable allocations,
although there is still plenty of free memory left in ZONE_MOVABLE.

Usually, MOVABLE:KERNEL ratios of up to 3:1 or even 4:1 are fine. Ratios of 63:1
are definitely impossible due to the overhead for the memory map.

Actual safe zone ratios depend on the workload. Extreme cases, like excessive
long-term pinning of pages, might not be able to deal with ZONE_MOVABLE at all.

.. note::

  CMA memory part of a kernel zone essentially behaves like memory in
  ZONE_MOVABLE and similar considerations apply, especially when combining
  CMA with ZONE_MOVABLE.

ZONE_MOVABLE Sizing Considerations
----------------------------------

We usually expect that a large portion of available system RAM will actually
be consumed by user space, either directly or indirectly via the page cache. In
the normal case, ZONE_MOVABLE can be used when allocating such pages just fine.

With that in mind, it makes sense that we can have a big portion of system RAM
managed by ZONE_MOVABLE. However, there are some things to consider when using
ZONE_MOVABLE, especially when fine-tuning zone ratios:

- Having a lot of offline memory blocks. Even offline memory blocks consume
  memory for metadata and page tables in the direct map; having a lot of offline
  memory blocks is not a typical case, though.

- Memory ballooning without balloon compaction is incompatible with
  ZONE_MOVABLE. Only some implementations, such as virtio-balloon and
  pseries CMM, fully support balloon compaction.

  Further, the CONFIG_BALLOON_COMPACTION kernel configuration option might be
  disabled. In that case, balloon inflation will only perform unmovable
  allocations and silently create a zone imbalance, usually triggered by
  inflation requests from the hypervisor.

- Gigantic pages are unmovable, resulting in user space consuming a
  lot of unmovable memory.

- Huge pages are unmovable when an architectures does not support huge
  page migration, resulting in a similar issue as with gigantic pages.

- Page tables are unmovable. Excessive swapping, mapping extremely large
  files or ZONE_DEVICE memory can be problematic, although only really relevant
  in corner cases. When we manage a lot of user space memory that has been
  swapped out or is served from a file/persistent memory/... we still need a lot
  of page tables to manage that memory once user space accessed that memory.

- In certain DAX configurations the memory map for the device memory will be
  allocated from the kernel zones.

- KASAN can have a significant memory overhead, for example, consuming 1/8th of
  the total system memory size as (unmovable) tracking metadata.

- Long-term pinning of pages. Techniques that rely on long-term pinnings
  (especially, RDMA and vfio/mdev) are fundamentally problematic with
  ZONE_MOVABLE, and therefore, memory offlining. Pinned pages cannot reside
  on ZONE_MOVABLE as that would turn these pages unmovable. Therefore, they
  have to be migrated off that zone while pinning. Pinning a page can fail
  even if there is plenty of free memory in ZONE_MOVABLE.

  In addition, using ZONE_MOVABLE might make page pinning more expensive,
  because of the page migration overhead.

By default, all the memory configured at boot time is managed by the kernel
zones and ZONE_MOVABLE is not used.

To enable ZONE_MOVABLE to include the memory present at boot and to control the
ratio between movable and kernel zones there are two command line options:
``kernelcore=`` and ``movablecore=``. See
Documentation/admin-guide/kernel-parameters.rst for their description.

Memory Offlining and ZONE_MOVABLE
---------------------------------

Even with ZONE_MOVABLE, there are some corner cases where offlining a memory
block might fail:

- Memory blocks with memory holes; this applies to memory blocks present during
  boot and can apply to memory blocks hotplugged via the XEN balloon and the
  Hyper-V balloon.

- Mixed NUMA nodes and mixed zones within a single memory block prevent memory
  offlining; this applies to memory blocks present during boot only.

- Special memory blocks prevented by the system from getting offlined. Examples
  include any memory available during boot on arm64 or memory blocks spanning
  the crashkernel area on s390x; this usually applies to memory blocks present
  during boot only.

- Memory blocks overlapping with CMA areas cannot be offlined, this applies to
  memory blocks present during boot only.

- Concurrent activity that operates on the same physical memory area, such as
  allocating gigantic pages, can result in temporary offlining failures.

- Out of memory when dissolving huge pages, especially when HugeTLB Vmemmap
  Optimization (HVO) is enabled.

  Offlining code may be able to migrate huge page contents, but may not be able
  to dissolve the source huge page because it fails allocating (unmovable) pages
  for the vmemmap, because the system might not have free memory in the kernel
  zones left.

  Users that depend on memory offlining to succeed for movable zones should
  carefully consider whether the memory savings gained from this feature are
  worth the risk of possibly not being able to offline memory in certain
  situations.

Further, when running into out of memory situations while migrating pages, or
when still encountering permanently unmovable pages within ZONE_MOVABLE
(-> BUG), memory offlining will keep retrying until it eventually succeeds.

When offlining is triggered from user space, the offlining context can be
terminated by sending a fatal signal. A timeout based offlining can easily be
implemented via::

	% timeout $TIMEOUT offline_block | failure_handling