Merge branch 'akpm' (patches from Andrew)

Merge misc updates from Andrew Morton:
 "257 patches.

  Subsystems affected by this patch series: scripts, ocfs2, vfs, and
  mm (slab-generic, slab, slub, kconfig, dax, kasan, debug, pagecache,
  gup, swap, memcg, pagemap, mprotect, mremap, iomap, tracing, vmalloc,
  pagealloc, memory-failure, hugetlb, userfaultfd, vmscan, tools,
  memblock, oom-kill, hugetlbfs, migration, thp, readahead, nommu, ksm,
  vmstat, madvise, memory-hotplug, rmap, zsmalloc, highmem, zram,
  cleanups, kfence, and damon)"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (257 commits)
  mm/damon: remove return value from before_terminate callback
  mm/damon: fix a few spelling mistakes in comments and a pr_debug message
  mm/damon: simplify stop mechanism
  Docs/admin-guide/mm/pagemap: wordsmith page flags descriptions
  Docs/admin-guide/mm/damon/start: simplify the content
  Docs/admin-guide/mm/damon/start: fix a wrong link
  Docs/admin-guide/mm/damon/start: fix wrong example commands
  mm/damon/dbgfs: add adaptive_targets list check before enable monitor_on
  mm/damon: remove unnecessary variable initialization
  Documentation/admin-guide/mm/damon: add a document for DAMON_RECLAIM
  mm/damon: introduce DAMON-based Reclamation (DAMON_RECLAIM)
  selftests/damon: support watermarks
  mm/damon/dbgfs: support watermarks
  mm/damon/schemes: activate schemes based on a watermarks mechanism
  tools/selftests/damon: update for regions prioritization of schemes
  mm/damon/dbgfs: support prioritization weights
  mm/damon/vaddr,paddr: support pageout prioritization
  mm/damon/schemes: prioritize regions within the quotas
  mm/damon/selftests: support schemes quotas
  mm/damon/dbgfs: support quotas of schemes
  ...
This commit is contained in:
Linus Torvalds
2021-11-06 14:08:17 -07:00
249 changed files with 6061 additions and 2089 deletions
@@ -328,6 +328,14 @@ as idle::
From now on, any pages on zram are idle pages. The idle mark
will be removed until someone requests access of the block.
IOW, unless there is access request, those pages are still idle pages.
Additionally, when CONFIG_ZRAM_MEMORY_TRACKING is enabled pages can be
marked as idle based on how long (in seconds) it's been since they were
last accessed::
echo 86400 > /sys/block/zramX/idle
In this example all pages which haven't been accessed in more than 86400
seconds (one day) will be marked idle.
Admin can request writeback of those idle pages at right timing via::
@@ -87,10 +87,8 @@ Brief summary of control files.
memory.oom_control set/show oom controls.
memory.numa_stat show the number of memory usage per numa
node
memory.kmem.limit_in_bytes set/show hard limit for kernel memory
This knob is deprecated and shouldn't be
used. It is planned that this be removed in
the foreseeable future.
memory.kmem.limit_in_bytes This knob is deprecated and writing to
it will return -ENOTSUPP.
memory.kmem.usage_in_bytes show current kernel memory allocation
memory.kmem.failcnt show the number of kernel memory usage
hits limits
@@ -518,11 +516,6 @@ will be charged as a new owner of it.
charged file caches. Some out-of-use page caches may keep charged until
memory pressure happens. If you want to avoid that, force_empty will be useful.
Also, note that when memory.kmem.limit_in_bytes is set the charges due to
kernel pages will still be seen. This is not considered a failure and the
write will still return success. In this case, it is expected that
memory.kmem.usage_in_bytes == memory.usage_in_bytes.
5.2 stat file
-------------
@@ -1582,8 +1582,10 @@
registers. Default set by CONFIG_HPET_MMAP_DEFAULT.
hugetlb_cma= [HW,CMA] The size of a CMA area used for allocation
of gigantic hugepages.
Format: nn[KMGTPE]
of gigantic hugepages. Or using node format, the size
of a CMA area per node can be specified.
Format: nn[KMGTPE] or (node format)
<node>:nn[KMGTPE][,<node>:nn[KMGTPE]]
Reserve a CMA area of given size and allocate gigantic
hugepages using the CMA allocator. If enabled, the
@@ -1594,9 +1596,11 @@
the number of pages of hugepagesz to be allocated.
If this is the first HugeTLB parameter on the command
line, it specifies the number of pages to allocate for
the default huge page size. See also
Documentation/admin-guide/mm/hugetlbpage.rst.
Format: <integer>
the default huge page size. If using node format, the
number of pages to allocate per-node can be specified.
See also Documentation/admin-guide/mm/hugetlbpage.rst.
Format: <integer> or (node format)
<node>:<integer>[,<node>:<integer>]
hugepagesz=
[HW] The size of the HugeTLB pages. This is used in
@@ -13,3 +13,4 @@ optimize those.
start
usage
reclaim
@@ -0,0 +1,235 @@
.. SPDX-License-Identifier: GPL-2.0
=======================
DAMON-based Reclamation
=======================
DAMON-based Reclamation (DAMON_RECLAIM) is a static kernel module that aimed to
be used for proactive and lightweight reclamation under light memory pressure.
It doesn't aim to replace the LRU-list based page_granularity reclamation, but
to be selectively used for different level of memory pressure and requirements.
Where Proactive Reclamation is Required?
========================================
On general memory over-committed systems, proactively reclaiming cold pages
helps saving memory and reducing latency spikes that incurred by the direct
reclaim of the process or CPU consumption of kswapd, while incurring only
minimal performance degradation [1]_ [2]_ .
Free Pages Reporting [3]_ based memory over-commit virtualization systems are
good example of the cases. In such systems, the guest VMs reports their free
memory to host, and the host reallocates the reported memory to other guests.
As a result, the memory of the systems are fully utilized. However, the
guests could be not so memory-frugal, mainly because some kernel subsystems and
user-space applications are designed to use as much memory as available. Then,
guests could report only small amount of memory as free to host, results in
memory utilization drop of the systems. Running the proactive reclamation in
guests could mitigate this problem.
How It Works?
=============
DAMON_RECLAIM finds memory regions that didn't accessed for specific time
duration and page out. To avoid it consuming too much CPU for the paging out
operation, a speed limit can be configured. Under the speed limit, it pages
out memory regions that didn't accessed longer time first. System
administrators can also configure under what situation this scheme should
automatically activated and deactivated with three memory pressure watermarks.
Interface: Module Parameters
============================
To use this feature, you should first ensure your system is running on a kernel
that is built with ``CONFIG_DAMON_RECLAIM=y``.
To let sysadmins enable or disable it and tune for the given system,
DAMON_RECLAIM utilizes module parameters. That is, you can put
``damon_reclaim.<parameter>=<value>`` on the kernel boot command line or write
proper values to ``/sys/modules/damon_reclaim/parameters/<parameter>`` files.
Note that the parameter values except ``enabled`` are applied only when
DAMON_RECLAIM starts. Therefore, if you want to apply new parameter values in
runtime and DAMON_RECLAIM is already enabled, you should disable and re-enable
it via ``enabled`` parameter file. Writing of the new values to proper
parameter values should be done before the re-enablement.
Below are the description of each parameter.
enabled
-------
Enable or disable DAMON_RECLAIM.
You can enable DAMON_RCLAIM by setting the value of this parameter as ``Y``.
Setting it as ``N`` disables DAMON_RECLAIM. Note that DAMON_RECLAIM could do
no real monitoring and reclamation due to the watermarks-based activation
condition. Refer to below descriptions for the watermarks parameter for this.
min_age
-------
Time threshold for cold memory regions identification in microseconds.
If a memory region is not accessed for this or longer time, DAMON_RECLAIM
identifies the region as cold, and reclaims it.
120 seconds by default.
quota_ms
--------
Limit of time for the reclamation in milliseconds.
DAMON_RECLAIM tries to use only up to this time within a time window
(quota_reset_interval_ms) for trying reclamation of cold pages. This can be
used for limiting CPU consumption of DAMON_RECLAIM. If the value is zero, the
limit is disabled.
10 ms by default.
quota_sz
--------
Limit of size of memory for the reclamation in bytes.
DAMON_RECLAIM charges amount of memory which it tried to reclaim within a time
window (quota_reset_interval_ms) and makes no more than this limit is tried.
This can be used for limiting consumption of CPU and IO. If this value is
zero, the limit is disabled.
128 MiB by default.
quota_reset_interval_ms
-----------------------
The time/size quota charge reset interval in milliseconds.
The charget reset interval for the quota of time (quota_ms) and size
(quota_sz). That is, DAMON_RECLAIM does not try reclamation for more than
quota_ms milliseconds or quota_sz bytes within quota_reset_interval_ms
milliseconds.
1 second by default.
wmarks_interval
---------------
Minimal time to wait before checking the watermarks, when DAMON_RECLAIM is
enabled but inactive due to its watermarks rule.
wmarks_high
-----------
Free memory rate (per thousand) for the high watermark.
If free memory of the system in bytes per thousand bytes is higher than this,
DAMON_RECLAIM becomes inactive, so it does nothing but only periodically checks
the watermarks.
wmarks_mid
----------
Free memory rate (per thousand) for the middle watermark.
If free memory of the system in bytes per thousand bytes is between this and
the low watermark, DAMON_RECLAIM becomes active, so starts the monitoring and
the reclaiming.
wmarks_low
----------
Free memory rate (per thousand) for the low watermark.
If free memory of the system in bytes per thousand bytes is lower than this,
DAMON_RECLAIM becomes inactive, so it does nothing but periodically checks the
watermarks. In the case, the system falls back to the LRU-list based page
granularity reclamation logic.
sample_interval
---------------
Sampling interval for the monitoring in microseconds.
The sampling interval of DAMON for the cold memory monitoring. Please refer to
the DAMON documentation (:doc:`usage`) for more detail.
aggr_interval
-------------
Aggregation interval for the monitoring in microseconds.
The aggregation interval of DAMON for the cold memory monitoring. Please
refer to the DAMON documentation (:doc:`usage`) for more detail.
min_nr_regions
--------------
Minimum number of monitoring regions.
The minimal number of monitoring regions of DAMON for the cold memory
monitoring. This can be used to set lower-bound of the monitoring quality.
But, setting this too high could result in increased monitoring overhead.
Please refer to the DAMON documentation (:doc:`usage`) for more detail.
max_nr_regions
--------------
Maximum number of monitoring regions.
The maximum number of monitoring regions of DAMON for the cold memory
monitoring. This can be used to set upper-bound of the monitoring overhead.
However, setting this too low could result in bad monitoring quality. Please
refer to the DAMON documentation (:doc:`usage`) for more detail.
monitor_region_start
--------------------
Start of target memory region in physical address.
The start physical address of memory region that DAMON_RECLAIM will do work
against. That is, DAMON_RECLAIM will find cold memory regions in this region
and reclaims. By default, biggest System RAM is used as the region.
monitor_region_end
------------------
End of target memory region in physical address.
The end physical address of memory region that DAMON_RECLAIM will do work
against. That is, DAMON_RECLAIM will find cold memory regions in this region
and reclaims. By default, biggest System RAM is used as the region.
kdamond_pid
-----------
PID of the DAMON thread.
If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread. Else,
-1.
Example
=======
Below runtime example commands make DAMON_RECLAIM to find memory regions that
not accessed for 30 seconds or more and pages out. The reclamation is limited
to be done only up to 1 GiB per second to avoid DAMON_RECLAIM consuming too
much CPU time for the paging out operation. It also asks DAMON_RECLAIM to do
nothing if the system's free memory rate is more than 50%, but start the real
works if it becomes lower than 40%. If DAMON_RECLAIM doesn't make progress and
therefore the free memory rate becomes lower than 20%, it asks DAMON_RECLAIM to
do nothing again, so that we can fall back to the LRU-list based page
granularity reclamation. ::
# cd /sys/modules/damon_reclaim/parameters
# echo 30000000 > min_age
# echo $((1 * 1024 * 1024 * 1024)) > quota_sz
# echo 1000 > quota_reset_interval_ms
# echo 500 > wmarks_high
# echo 400 > wmarks_mid
# echo 200 > wmarks_low
# echo Y > enabled
.. [1] https://research.google/pubs/pub48551/
.. [2] https://lwn.net/Articles/787611/
.. [3] https://www.kernel.org/doc/html/latest/vm/free_page_reporting.html
+70 -50
View File
@@ -6,39 +6,9 @@ Getting Started
This document briefly describes how you can use DAMON by demonstrating its
default user space tool. Please note that this document describes only a part
of its features for brevity. Please refer to :doc:`usage` for more details.
TL; DR
======
Follow the commands below to monitor and visualize the memory access pattern of
your workload. ::
# # build the kernel with CONFIG_DAMON_*=y, install it, and reboot
# mount -t debugfs none /sys/kernel/debug/
# git clone https://github.com/awslabs/damo
# ./damo/damo record $(pidof <your workload>)
# ./damo/damo report heat --plot_ascii
The final command draws the access heatmap of ``<your workload>``. The heatmap
shows which memory region (x-axis) is accessed when (y-axis) and how frequently
(number; the higher the more accesses have been observed). ::
111111111111111111111111111111111111111111111111111111110000
111121111111111111111111111111211111111111111111111111110000
000000000000000000000000000000000000000000000000001555552000
000000000000000000000000000000000000000000000222223555552000
000000000000000000000000000000000000000011111677775000000000
000000000000000000000000000000000000000488888000000000000000
000000000000000000000000000000000177888400000000000000000000
000000000000000000000000000046666522222100000000000000000000
000000000000000000000014444344444300000000000000000000000000
000000000000000002222245555510000000000000000000000000000000
# access_frequency: 0 1 2 3 4 5 6 7 8 9
# x-axis: space (140286319947776-140286426374096: 101.496 MiB)
# y-axis: time (605442256436361-605479951866441: 37.695430s)
# resolution: 60x10 (1.692 MiB and 3.770s for each character)
of its features for brevity. Please refer to the usage `doc
<https://github.com/awslabs/damo/blob/next/USAGE.md>`_ of the tool for more
details.
Prerequisites
@@ -91,24 +61,74 @@ pattern in the ``damon.data`` file.
Visualizing Recorded Patterns
=============================
The following three commands visualize the recorded access patterns and save
the results as separate image files. ::
You can visualize the pattern in a heatmap, showing which memory region
(x-axis) got accessed when (y-axis) and how frequently (number).::
$ damo report heats --heatmap access_pattern_heatmap.png
$ damo report wss --range 0 101 1 --plot wss_dist.png
$ damo report wss --range 0 101 1 --sortby time --plot wss_chron_change.png
$ sudo damo report heats --heatmap stdout
22222222222222222222222222222222222222211111111111111111111111111111111111111100
44444444444444444444444444444444444444434444444444444444444444444444444444443200
44444444444444444444444444444444444444433444444444444444444444444444444444444200
33333333333333333333333333333333333333344555555555555555555555555555555555555200
33333333333333333333333333333333333344444444444444444444444444444444444444444200
22222222222222222222222222222222222223355555555555555555555555555555555555555200
00000000000000000000000000000000000000288888888888888888888888888888888888888400
00000000000000000000000000000000000000288888888888888888888888888888888888888400
33333333333333333333333333333333333333355555555555555555555555555555555555555200
88888888888888888888888888888888888888600000000000000000000000000000000000000000
88888888888888888888888888888888888888600000000000000000000000000000000000000000
33333333333333333333333333333333333333444444444444444444444444444444444444443200
00000000000000000000000000000000000000288888888888888888888888888888888888888400
[...]
# access_frequency: 0 1 2 3 4 5 6 7 8 9
# x-axis: space (139728247021568-139728453431248: 196.848 MiB)
# y-axis: time (15256597248362-15326899978162: 1 m 10.303 s)
# resolution: 80x40 (2.461 MiB and 1.758 s for each character)
- ``access_pattern_heatmap.png`` will visualize the data access pattern in a
heatmap, showing which memory region (y-axis) got accessed when (x-axis)
and how frequently (color).
- ``wss_dist.png`` will show the distribution of the working set size.
- ``wss_chron_change.png`` will show how the working set size has
chronologically changed.
You can also visualize the distribution of the working set size, sorted by the
size.::
You can view the visualizations of this example workload at [1]_.
Visualizations of other realistic workloads are available at [2]_ [3]_ [4]_.
$ sudo damo report wss --range 0 101 10
# <percentile> <wss>
# target_id 18446632103789443072
# avr: 107.708 MiB
0 0 B | |
10 95.328 MiB |**************************** |
20 95.332 MiB |**************************** |
30 95.340 MiB |**************************** |
40 95.387 MiB |**************************** |
50 95.387 MiB |**************************** |
60 95.398 MiB |**************************** |
70 95.398 MiB |**************************** |
80 95.504 MiB |**************************** |
90 190.703 MiB |********************************************************* |
100 196.875 MiB |***********************************************************|
.. [1] https://damonitor.github.io/doc/html/v17/admin-guide/mm/damon/start.html#visualizing-recorded-patterns
.. [2] https://damonitor.github.io/test/result/visual/latest/rec.heatmap.1.png.html
.. [3] https://damonitor.github.io/test/result/visual/latest/rec.wss_sz.png.html
.. [4] https://damonitor.github.io/test/result/visual/latest/rec.wss_time.png.html
Using ``--sortby`` option with the above command, you can show how the working
set size has chronologically changed.::
$ sudo damo report wss --range 0 101 10 --sortby time
# <percentile> <wss>
# target_id 18446632103789443072
# avr: 107.708 MiB
0 3.051 MiB | |
10 190.703 MiB |***********************************************************|
20 95.336 MiB |***************************** |
30 95.328 MiB |***************************** |
40 95.387 MiB |***************************** |
50 95.332 MiB |***************************** |
60 95.320 MiB |***************************** |
70 95.398 MiB |***************************** |
80 95.398 MiB |***************************** |
90 95.340 MiB |***************************** |
100 95.398 MiB |***************************** |
Data Access Pattern Aware Memory Management
===========================================
Below three commands make every memory region of size >=4K that doesn't
accessed for >=60 seconds in your workload to be swapped out. ::
$ echo "#min-size max-size min-acc max-acc min-age max-age action" > test_scheme
$ echo "4K max 0 0 60s max pageout" >> test_scheme
$ damo schemes -c test_scheme <pid of your workload>
+104 -5
View File
@@ -10,15 +10,16 @@ DAMON provides below three interfaces for different users.
This is for privileged people such as system administrators who want a
just-working human-friendly interface. Using this, users can use the DAMONs
major features in a human-friendly way. It may not be highly tuned for
special cases, though. It supports only virtual address spaces monitoring.
special cases, though. It supports both virtual and physical address spaces
monitoring.
- *debugfs interface.*
This is for privileged user space programmers who want more optimized use of
DAMON. Using this, users can use DAMONs major features by reading
from and writing to special debugfs files. Therefore, you can write and use
your personalized DAMON debugfs wrapper programs that reads/writes the
debugfs files instead of you. The DAMON user space tool is also a reference
implementation of such programs. It supports only virtual address spaces
monitoring.
implementation of such programs. It supports both virtual and physical
address spaces monitoring.
- *Kernel Space Programming Interface.*
This is for kernel space programmers. Using this, users can utilize every
feature of DAMON most flexibly and efficiently by writing kernel space
@@ -34,8 +35,9 @@ the reason, this document describes only the debugfs interface
debugfs Interface
=================
DAMON exports three files, ``attrs``, ``target_ids``, and ``monitor_on`` under
its debugfs directory, ``<debugfs>/damon/``.
DAMON exports five files, ``attrs``, ``target_ids``, ``init_regions``,
``schemes`` and ``monitor_on`` under its debugfs directory,
``<debugfs>/damon/``.
Attributes
@@ -71,9 +73,106 @@ check it again::
# 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. Each line
of the input should represent one region in below form.::
<target id> <start address> <end address>
The ``target id`` should already in ``target_ids`` file, 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 process 42, and another couple of address ranges, ``20-40`` and
``50-100`` as that of process 4242.::
# cd <debugfs>/damon
# echo "42 1 100
42 100 200
4242 20 40
4242 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 ``regions update interval``. Therefore, users should set the
``regions 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 size having a specific access frequency for a specific
time. DAMON receives such formalized operation schemes from the user and
applies those to the target processes. It also counts the total number and
size of regions that each scheme is applied. This statistics can be used for
online analysis or tuning of the schemes.
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:
min-size max-size min-acc max-acc min-age max-age action
Note that the ranges are closed interval. 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``), and a
predefined integer for memory management actions should be used. 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
You can disable schemes by simply writing an empty string to the file. For
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", check the entered scheme again, and
finally remove the scheme. ::
# cd <debugfs>/damon
# echo "4096 8192 0 5 10 20 2" > schemes
# cat schemes
4096 8192 0 5 10 20 2 0 0
# echo > schemes
The last two integers in the 4th line of above example is the total number and
the total size of the regions that the scheme is applied.
Turning On/Off
--------------
+39 -3
View File
@@ -128,7 +128,9 @@ hugepages
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.
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::
@@ -138,6 +140,14 @@ hugepages
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
@@ -234,8 +244,12 @@ will exist, of the form::
hugepages-${size}kB
Inside each of these directories, the same set of files will exist::
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
@@ -243,7 +257,29 @@ Inside each of these directories, the same set of files will exist::
resv_hugepages
surplus_hugepages
which function as described above for the default huge page-sized case.
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:
+2
View File
@@ -37,5 +37,7 @@ the Linux memory management.
numaperf
pagemap
soft-dirty
swap_numa
transhuge
userfaultfd
zswap
+121 -20
View File
@@ -165,9 +165,8 @@ Or alternatively::
% echo 1 > /sys/devices/system/memory/memoryXXX/online
The kernel will select the target zone automatically, usually defaulting to
``ZONE_NORMAL`` unless ``movablecore=1`` has been specified on the kernel
command line or if the memory block would intersect the ZONE_MOVABLE already.
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::
@@ -198,6 +197,9 @@ Auto-onlining can be enabled by writing ``online``, ``online_kernel`` or
% 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.
@@ -393,11 +395,16 @@ command line parameters are relevant:
======================== =======================================================
``memhp_default_state`` configure auto-onlining by essentially setting
``/sys/devices/system/memory/auto_online_blocks``.
``movablecore`` configure automatic zone selection of the kernel. When
set, the kernel will default to ZONE_MOVABLE, unless
other zones can be kept contiguous.
``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
------------------
@@ -410,24 +417,118 @@ them with ``memory_hotplug.`` such as::
and they can be observed (and some even modified at runtime) via::
/sys/modules/memory_hotplug/parameters/
/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.
================================ ===============================================
``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.
======================== =======================================================
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
============
+27 -26
View File
@@ -90,13 +90,14 @@ Short descriptions to the page flags
====================================
0 - LOCKED
page is being locked for exclusive access, e.g. by undergoing read/write IO
The page is being locked for exclusive access, e.g. by undergoing read/write
IO.
7 - SLAB
page is managed by the SLAB/SLOB/SLUB/SLQB kernel memory allocator
The page is managed by the SLAB/SLOB/SLUB/SLQB kernel memory allocator.
When compound page is used, SLUB/SLQB will only set this flag on the head
page; SLOB will not flag it at all.
10 - BUDDY
a free memory block managed by the buddy system allocator
A free memory block managed by the buddy system allocator.
The buddy system organizes free memory in blocks of various orders.
An order N block has 2^N physically contiguous pages, with the BUDDY flag
set for and _only_ for the first page.
@@ -112,65 +113,65 @@ Short descriptions to the page flags
16 - COMPOUND_TAIL
A compound page tail (see description above).
17 - HUGE
this is an integral part of a HugeTLB page
This is an integral part of a HugeTLB page.
19 - HWPOISON
hardware detected memory corruption on this page: don't touch the data!
Hardware detected memory corruption on this page: don't touch the data!
20 - NOPAGE
no page frame exists at the requested address
No page frame exists at the requested address.
21 - KSM
identical memory pages dynamically shared between one or more processes
Identical memory pages dynamically shared between one or more processes.
22 - THP
contiguous pages which construct transparent hugepages
Contiguous pages which construct transparent hugepages.
23 - OFFLINE
page is logically offline
The page is logically offline.
24 - ZERO_PAGE
zero page for pfn_zero or huge_zero page
Zero page for pfn_zero or huge_zero page.
25 - IDLE
page has not been accessed since it was marked idle (see
The page has not been accessed since it was marked idle (see
:ref:`Documentation/admin-guide/mm/idle_page_tracking.rst <idle_page_tracking>`).
Note that this flag may be stale in case the page was accessed via
a PTE. To make sure the flag is up-to-date one has to read
``/sys/kernel/mm/page_idle/bitmap`` first.
26 - PGTABLE
page is in use as a page table
The page is in use as a page table.
IO related page flags
---------------------
1 - ERROR
IO error occurred
IO error occurred.
3 - UPTODATE
page has up-to-date data
The page has up-to-date data.
ie. for file backed page: (in-memory data revision >= on-disk one)
4 - DIRTY
page has been written to, hence contains new data
The page has been written to, hence contains new data.
i.e. for file backed page: (in-memory data revision > on-disk one)
8 - WRITEBACK
page is being synced to disk
The page is being synced to disk.
LRU related page flags
----------------------
5 - LRU
page is in one of the LRU lists
The page is in one of the LRU lists.
6 - ACTIVE
page is in the active LRU list
The page is in the active LRU list.
18 - UNEVICTABLE
page is in the unevictable (non-)LRU list It is somehow pinned and
The page is in the unevictable (non-)LRU list It is somehow pinned and
not a candidate for LRU page reclaims, e.g. ramfs pages,
shmctl(SHM_LOCK) and mlock() memory segments
shmctl(SHM_LOCK) and mlock() memory segments.
2 - REFERENCED
page has been referenced since last LRU list enqueue/requeue
The page has been referenced since last LRU list enqueue/requeue.
9 - RECLAIM
page will be reclaimed soon after its pageout IO completed
The page will be reclaimed soon after its pageout IO completed.
11 - MMAP
a memory mapped page
A memory mapped page.
12 - ANON
a memory mapped page that is not part of a file
A memory mapped page that is not part of a file.
13 - SWAPCACHE
page is mapped to swap space, i.e. has an associated swap entry
The page is mapped to swap space, i.e. has an associated swap entry.
14 - SWAPBACKED
page is backed by swap/RAM
The page is backed by swap/RAM.
The page-types tool in the tools/vm directory can be used to query the
above flags.
@@ -57,7 +57,6 @@ The third argument (arg) passes a pointer of struct memory_notify::
unsigned long start_pfn;
unsigned long nr_pages;
int status_change_nid_normal;
int status_change_nid_high;
int status_change_nid;
}
@@ -65,8 +64,6 @@ The third argument (arg) passes a pointer of struct memory_notify::
- nr_pages is # of pages of online/offline memory.
- status_change_nid_normal is set node id when N_NORMAL_MEMORY of nodemask
is (will be) set/clear, if this is -1, then nodemask status is not changed.
- status_change_nid_high is set node id when N_HIGH_MEMORY of nodemask
is (will be) set/clear, if this is -1, then nodemask status is not changed.
- status_change_nid is set node id when N_MEMORY of nodemask is (will be)
set/clear. It means a new(memoryless) node gets new memory by online and a
node loses all memory. If this is -1, then nodemask status is not changed.
+19 -4
View File
@@ -231,10 +231,14 @@ Guarded allocations are set up based on the sample interval. After expiration
of the sample interval, the next allocation through the main allocator (SLAB or
SLUB) returns a guarded allocation from the KFENCE object pool (allocation
sizes up to PAGE_SIZE are supported). At this point, the timer is reset, and
the next allocation is set up after the expiration of the interval. To "gate" a
KFENCE allocation through the main allocator's fast-path without overhead,
KFENCE relies on static branches via the static keys infrastructure. The static
branch is toggled to redirect the allocation to KFENCE.
the next allocation is set up after the expiration of the interval.
When using ``CONFIG_KFENCE_STATIC_KEYS=y``, KFENCE allocations are "gated"
through the main allocator's fast-path by relying on static branches via the
static keys infrastructure. The static branch is toggled to redirect the
allocation to KFENCE. Depending on sample interval, target workloads, and
system architecture, this may perform better than the simple dynamic branch.
Careful benchmarking is recommended.
KFENCE objects each reside on a dedicated page, at either the left or right
page boundaries selected at random. The pages to the left and right of the
@@ -269,6 +273,17 @@ tail of KFENCE's freelist, so that the least recently freed objects are reused
first, and the chances of detecting use-after-frees of recently freed objects
is increased.
If pool utilization reaches 75% (default) or above, to reduce the risk of the
pool eventually being fully occupied by allocated objects yet ensure diverse
coverage of allocations, KFENCE limits currently covered allocations of the
same source from further filling up the pool. The "source" of an allocation is
based on its partial allocation stack trace. A side-effect is that this also
limits frequent long-lived allocations (e.g. pagecache) of the same source
filling up the pool permanently, which is the most common risk for the pool
becoming full and the sampled allocation rate dropping to zero. The threshold
at which to start limiting currently covered allocations can be configured via
the boot parameter ``kfence.skip_covered_thresh`` (pool usage%).
Interface
---------
@@ -63,7 +63,6 @@ memory_notify结构体的指针::
unsigned long start_pfn;
unsigned long nr_pages;
int status_change_nid_normal;
int status_change_nid_high;
int status_change_nid;
}
@@ -74,9 +73,6 @@ memory_notify结构体的指针::
- status_change_nid_normal是当nodemask的N_NORMAL_MEMORY被设置/清除时设置节
点id,如果是-1,则nodemask状态不改变。
- status_change_nid_high是当nodemask的N_HIGH_MEMORY被设置/清除时设置的节点
id,如果这个值为-1,那么nodemask状态不会改变。
- status_change_nid是当nodemask的N_MEMORY被(将)设置/清除时设置的节点id。这
意味着一个新的(没上线的)节点通过联机获得新的内存,而一个节点失去了所有的内
存。如果这个值为-1,那么nodemask的状态就不会改变。
+18 -11
View File
@@ -35,13 +35,17 @@ two parts:
1. Identification of the monitoring target address range for the address space.
2. Access check of specific address range in the target space.
DAMON currently provides the implementation of the primitives for only the
virtual address spaces. Below two subsections describe how it works.
DAMON currently provides the implementations of the primitives for the physical
and virtual address spaces. Below two subsections describe how those work.
VMA-based Target Address Range Construction
-------------------------------------------
This is only for the virtual address space primitives implementation. That for
the physical address space simply asks users to manually set the monitoring
target address ranges.
Only small parts in the super-huge virtual address space of the processes are
mapped to the physical memory and accessed. Thus, tracking the unmapped
address regions is just wasteful. However, because DAMON can deal with some
@@ -71,15 +75,18 @@ to make a reasonable trade-off. Below shows this in detail::
PTE Accessed-bit Based Access Check
-----------------------------------
The implementation for the virtual address space uses PTE Accessed-bit for
basic access checks. It finds the relevant PTE Accessed bit from the address
by walking the page table for the target task of the address. In this way, the
implementation finds and clears the bit for next sampling target address and
checks whether the bit set again after one sampling period. This could disturb
other kernel subsystems using the Accessed bits, namely Idle page tracking and
the reclaim logic. To avoid such disturbances, DAMON makes it mutually
exclusive with Idle page tracking and uses ``PG_idle`` and ``PG_young`` page
flags to solve the conflict with the reclaim logic, as Idle page tracking does.
Both of the implementations for physical and virtual address spaces use PTE
Accessed-bit for basic access checks. Only one difference is the way of
finding the relevant PTE Accessed bit(s) from the address. While the
implementation for the virtual address walks the page table for the target task
of the address, the implementation for the physical address walks every page
table having a mapping to the address. In this way, the implementations find
and clear the bit(s) for next sampling target address and checks whether the
bit(s) set again after one sampling period. This could disturb other kernel
subsystems using the Accessed bits, namely Idle page tracking and the reclaim
logic. To avoid such disturbances, DAMON makes it mutually exclusive with Idle
page tracking and uses ``PG_idle`` and ``PG_young`` page flags to solve the
conflict with the reclaim logic, as Idle page tracking does.
Address Space Independent Core Mechanisms
+2 -3
View File
@@ -36,10 +36,9 @@ constructions and actual access checks can be implemented and configured on the
DAMON core by the users. In this way, DAMON users can monitor any address
space with any access check technique.
Nonetheless, DAMON provides vma tracking and PTE Accessed bit check based
Nonetheless, DAMON provides vma/rmap tracking and PTE Accessed bit check based
implementations of the address space dependent functions for the virtual memory
by default, for a reference and convenient use. In near future, we will
provide those for physical memory address space.
and the physical memory by default, for a reference and convenient use.
Can I simply monitor page granularity?
-1
View File
@@ -27,4 +27,3 @@ workloads and systems.
faq
design
api
plans
+5 -21
View File
@@ -3,27 +3,11 @@ Linux Memory Management Documentation
=====================================
This is a collection of documents about the Linux memory management (mm)
subsystem. If you are looking for advice on simply allocating memory,
see the :ref:`memory_allocation`.
User guides for MM features
===========================
The following documents provide guides for controlling and tuning
various features of the Linux memory management
.. toctree::
:maxdepth: 1
swap_numa
zswap
Kernel developers MM documentation
==================================
The below documents describe MM internals with different level of
details ranging from notes and mailing list responses to elaborate
descriptions of data structures and algorithms.
subsystem internals with different level of details ranging from notes and
mailing list responses for elaborating descriptions of data structures and
algorithms. If you are looking for advice on simply allocating memory, see the
:ref:`memory_allocation`. For controlling and tuning guides, see the
:doc:`admin guide <../admin-guide/mm/index>`.
.. toctree::
:maxdepth: 1

Some files were not shown because too many files have changed in this diff Show More