もともと、Linux Kernelのソースコードの一部なので、GPLv2扱いになる(はずの認識)。
https://www.kernel.org/doc/html/latest/index.html
Licensing documentation
The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.
https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing
Concepts overview
The memory management in Linux is a complex system that evolved over the years and included more and more functionality to support a variety of systems from MMU-less microcontrollers to supercomputers.
Linuxのメモリ管理は、長年にわたって改良がされ、MMUの存在しないマイクロコントローラーからスーパーコンピュータにわたるまで多様なシステムをサポートする機能性を持つ、複雑なシステムである。
The memory management for systems without an MMU is called
nommu
and it definitely deserves a dedicated document, which hopefully will be eventually written.
MMUを所持しないシステムのメモリ管理はnommu
と呼ばれる。そして、専用のドキュメントが提供されることに値する事は間違いないことでしょう。
Yet, although some of the concepts are the same, here we assume that an MMU is available and a CPU can translate a virtual address to a physical address.
ただし、一部の概念は同じであるが、MMUが利用可能であり、CPUが仮想アドレスから物理アドレスへ変換が可能なMMUがあると想定しています。
Virtual Memory Primer
The physical memory in a computer system is a limited resource and even for systems that support memory hotplug there is a hard limit on the amount of memory that can be installed.
コンピュータシステムの物理メモリは、制限のあるリソースであり、仮にシステムがメモリのhotplugをサポートしていたとしても、装着可能なメモリの搭載量にはハード制約が存在します。
The physical memory is not necessarily contiguous; it might be accessible as a set of distinct address ranges.
物理メモリは連続性が必須ではありません。時として個別のアドレス範囲としてアクセス可能である場合があります。
Besides, different CPU architectures, and even different implementations of the same architecture have different views of how these address ranges are defined.
そのうえ、異なるCPUアーキテクチャ、あるいは同じアーキテクチャであっても異なる実装であれば、アドレス範囲が異なる見え方を有していることもあります。
.
All this makes dealing directly with physical memory quite complex and to avoid this complexity a concept of virtual memory was developed.
これにより物理メモリを直接扱うことが非常に複雑となり、この複雑さを回避するために仮想メモリの概念が開発されました。
The virtual memory abstracts the details of physical memory from the application software, allows to keep only needed information in the physical memory (demand paging) and provides a mechanism for the protection and controlled sharing of data between processes.
仮想メモリでは物理メモリの詳細をアプリケーションソフトウェアに対して抽象化します、これによって、物理メモリ(ページ要求)に保持できるようにし、データの保護とデータの共有のためのメカニズムをプロセス間に提供します。
.
With virtual memory, each and every memory access uses a virtual address.
仮想メモリを用いる場合、全てのメモリアクセスは仮想アドレスを介します。
When the CPU decodes the an instruction that reads (or writes) from (or to) the system memory, it translates the virtual
address encoded in that instruction to a physical
address that the memory controller can understand.
CPUがシステムメモリからread、もしくはシステムからへwriteする命令をdecodeすると、それは、メモリコントローラが理解できるように、仮想アドレス
を物理アドレス
に変換します。
.
The physical system memory is divided into page frames, or pages.
物理システムメモリは、page framesあるいはpagesに分割されます。
The size of each page is architecture specific.
それぞれのpageのサイズは、アーキテクチャ依存です。
Some architectures allow selection of the page size from several supported values; this selection is performed at the kernel build time by setting an appropriate kernel configuration option.
アーキテクチャによってはページサイズをいくつかサポートしている値から選択できるものもあります。この選択はカーネルをビルドするタイミングでkernel configuration optionで選択する事ができます。
.
Each physical memory page can be mapped as one or more virtual pages.
それぞれの物理メモリページは、1つ以上の仮想ページにマッピングすることができます。
These mappings are described by page tables that allow translation from a virtual address used by programs to the physical memory address. The page tables are organized hierarchically.
このマッピングはpage tablesに記載されます、これによって物理アドレスはプログラムによって物理メモリ亜連れ須に変換されます。このページテーブルは、階層的に組織化されています。
.
The tables at the lowest level of the hierarchy contain physical addresses of actual pages used by the software.
階層の最下層のテーブルには、ソフトウェアが利用する実際のページの物理アドレスが含まれます。
The tables at higher levels contain physical addresses of the pages belonging to the lower levels.
上位層のテーブルには、下位層に含まれるページの物理アドレスが含まれます。
The pointer to the top level page table resides in a register.
最上位のテーブルのポインターにはレジスタにあります。
When the CPU performs the address translation, it uses this register to access the top level page table.
CPUがアドレス変換しようとすると、それは最上位ページテーブルを介してそのレジスタを用いtます。
The high bits of the virtual address are used to index an entry in the top level page table.
仮想アドレスの上位ビットは、上位層ページテーブル内のエントリーを示すのに用いられます。
That entry is then used to access the next level in the hierarchy with the next bits of the virtual address as the index to that level page table.
そのエントリは、仮想アドレスの次のビットをそのレベルのページテーブルへのインデックスとして使用して、階層内の次のレベルにアクセスするために使用されます。
The lowest bits in the virtual address define the offset inside the actual page.
仮想アドレスの最下位のbitsは、実際のページのオフセットを定義します。
Huge Pages
The address translation requires several memory accesses and memory accesses are slow relatively to CPU speed.
アドレス変換は何度かのメモリアクセスを要求し、メモリアクセスはCPU速度に比べると遅い。
To avoid spending precious processor cycles on the address translation, CPUs maintain a cache of such translations called Translation Lookaside Buffer (or TLB).
アドレス変換に貴重なプロセスサイクルを用いるのを回避するべく、CPUにはTranslation Lookaside Buffer(TLB)と呼ばれる変換キャッシュを有している。
Usually TLB is pretty scarce resource and applications with large memory working set will experience performance hit because of TLB misses.
通常、TLBは非常に少ないリソースであり、大きなメモリ利用セットにおいては、TLB missがパフォーマンスを低下させます。
.
Many modern CPU architectures allow mapping of the memory pages directly by the higher levels in the page table. For instance, on x86, it is possible to map 2M and even 1G pages using entries in the second and the third level page tables.
最新のCPUアーキテクチャの大木は、ページテーブルの上位層でメモリページを直接マッピングできます。例えば、x86では2番目と3番目のページテーブルのエントリを用いて、2Mと1Gのマッピングができます。
In Linux such pages are called
huge
.
Linuxではこれをhuge
と呼んでいます。
Usage of huge pages significantly reduces pressure on TLB, improves TLB hit-rate and thus improves overall system performance.
Huge pageの用いると、TLBへの圧力を低下させることができます。TLB hit-rateを増やし、システム全体のパフォーマンスを向上します。
.
There are two mechanisms in Linux that enable mapping of the physical memory with the huge pages.
Linuxには、物理メモリとhuge pagesをマッピングするために、2つのメカニズムがあります。
The first one is
HugeTLB filesystem
, or hugetlbfs.
1つ目は、"HugeTLB filesystem" , hugetlbfsです。
It is a pseudo filesystem that uses RAM as its backing store. For the files created in this filesystem the data resides in the memory and mapped using huge pages.
これは、RAMを記録媒体に利用した疑似ファイルシステムです。このファイルシステムにファイルが生成されると、データはメモリに常駐し、huge pagesがマッピングされます。
The hugetlbfs is described at Documentation/admin-guide/mm/hugetlbpage.rst <hugetlbpage>
.
The hugetlbfsについては、Documentation/admin-guide/mm/hugetlbpage.rst <hugetlbpage>
に記載があります。
.
Another, more recent, mechanism that enables use of the huge pages is called Transparent HugePages
, or THP.
別の、もっと新しいhuge pagesを有効化するメカニズムは、Transparent HugePages
THPと呼ばれます。
Unlike the hugetlbfs that requires users and/or system administrators to configure what parts of the system memory should and can be mapped by the huge pages, THP manages such mappings transparently to the user and hence the name.
ユーザーやシステム管理者がシステムメモリのどの部分を構成する必要があるか、huge pagesによってマッピングできるかを要求するhugetlbfsと違って、THPはユーザーと名前に対して等価的なマッピングを提供します。
See Documentation/admin-guide/mm/transhuge.rst <admin_guide_transhuge>
for more details about THP.
Zones
Often hardware poses restrictions on how different physical memory ranges can be accessed.
多くの場合、ハードウェアは様々な物理メモリ範囲へのアクセス方法に制限を課します。
In some cases, devices cannot perform DMA to all the addressable memory.
場合によっては、デバイスはすべてのアドレス可能なメモリに対してDMAを実行できません。
In other cases, the size of the physical memory exceeds the maximal addressable size of virtual memory and special actions are required to access portions of the memory.
他のケースとしては、物理メモリのサイズが仮想メモリのアドレス可能な最大サイズを超えていると、メモリの一部にアクセスするのに特別なアクションが必要になります。
Linux groups memory pages into
zones
according to their possible usage.
Linux ではそのような使い方をするために、zone
というmemory pages を組織立てました。
For example, ZONE_DMA will contain memory that can be used by devices for DMA, ZONE_HIGHMEM will contain memory that is not permanently mapped into kernel's address space and ZONE_NORMAL will contain normally addressed pages.
例えば、ZONE_DMAはDMAによってデバイスが利用可能なメモリを含みます。DONE_HIGHMEMはカーネルアドレス空間において永続的ではないメモリが含まれます。ZONE_NORMALには通常のアドレスされたページが含まれます。
.
The actual layout of the memory zones is hardware dependent as not all architectures define all zones, and requirements for DMA are different for different platforms.
memory zoneの実際のレイアウトはハードウェアに依存します。すべてのアーキテクチャがすべてのzoneを定義するわけではありません。DMAの要件は異なるプラットフォームではことなります。
Nodes
Many multi-processor machines are NUMA - Non-Uniform Memory Access - systems.
多くのマルチプロセッサマシンは、NUMA ( Non-Uniform Memory Access) システムです。
In such systems the memory is arranged into banks that have different access latency depending on the "distance" from the processor.
そのようなシステムでは、メモリはいくつかのバンクに分割され、プロセッサからの"distance"によって異なるlatencyでアクセスされます。
Each bank is referred to as a
node
and for each node Linux constructs an independent memory management subsystem.
それぞれのbankは、nodeとして参照されます。それぞれのノードは、独立したメモリマネージメントサブシステムを構成します。
A node has its own set of zones, lists of free and used pages and various statistics counters.
nodeは、独自のzoneの集合、空きと使用済みのページのリスト、そして、様々な統計情報カウンターがあります。
You can find more details about NUMA in
Documentation/vm/numa.rst <numa>
and in
Documentation/admin-guide/mm/numa_memory_policy.rst <numa_memory_policy>
.
Page cache
The physical memory is volatile and the common case for getting data into the memory is to read it from files.
物理メモリは揮発性であり、データをメモリに取り込む一般的なケースはファイルからデータを読み込むことです。
Whenever a file is read, the data is put into the
page cache
to avoid expensive disk access on the subsequent reads.
ファイルを読み込むたびに、データはpage cache
に入れられると、以降の読み取りでコストの高いディスクアクセスを回避できます。
Similarly, when one writes to a file, the data is placed in the page cache and eventually gets into the backing storage device.
同様に、ファイルに書き込む場合でも、データをpage cacheに配置し、最終的には、backing storage deviceに格納されます。
The written pages are marked as
dirty
and when Linux decides to reuse them for other purposes, it makes sure to synchronize the file contents on the device with the updated data.
書き込まれたpagesはdirty
としてマークがされ、linuxが他の目的でそれを再利用しようとした場合、デバイス上のファイルの内容を更新済みのデータと確実に同期させます。
Anonymous Memory
The
anonymous memory
oranonymous mappings
represent memory that is not backed by a filesystem.
anonymous memory
or anonymous mappings
は、ファイルシステムにサポートされていないメモリです。
Such mappings are implicitly created for program's stack and heap or by explicit calls to mmap(2) system call.
このようなマッピングは、プログラムのスタックとヒープで暗黙的に実装される、あるいは、mmap(2) system callの明示的な呼び出しで実装されます。
Usually, the anonymous mappings only define virtual memory areas that the program is allowed to access.
通常、anonymous mappingはプログラムがアクセスできる仮想メモリ領域のみを定義します。
The read accesses will result in creation of a page table entry that references a special physical page filled with zeroes.
読み取りアクセスの結果、0でfillされた特別な物理ページを参照するpage table entryを生成されます。
When the program performs a write, a regular physical page will be allocated to hold the written data.
プログラムが書き込みを実行すると、書き込まれたデータを保持するために、通常の物理ページが割り当てられます。
The page will be marked dirty and if the kernel decides to repurpose it, the dirty page will be swapped out.
このページはdirtyがマークされ、再利用すべきとカーネルが判断したら、dirty pageはswapped outされます。
Reclaim
Throughout the system lifetime, a physical page can be used for storing different types of data.
システムのライフタイム全体を通して、物理ページは様々な種別のデータを保持するのに利用されます。
It can be kernel internal data structures, DMA'able buffers for device drivers use, data read from a filesystem, memory allocated by user space processes etc.
カーネルの内部データ構造、デバイスドライバーが使用するためのDMA可能なバッファー、ファイルシステムから読み取られたデータ、ユーザー空間プロセスによって割り当てられたメモリなどです。
.
Depending on the page usage it is treated differently by the Linux memory management.
ページの使用状況に応じ、Linux メモリ管理では扱い方が異なります。
The pages that can be freed at any time, either because they cache the data available elsewhere, for instance, on a hard disk, or because they can be swapped out, again, to the hard disk, are called reclaimable
.
ハードディスクなどの他の場所で利用可能なデータをキャッシュする、または再びハードディスクにスワップアウトできるための、いつでも解放できるページは「reclaimable」と呼ばれます。
The most notable categories of the reclaimable pages are page cache and anonymous memory.
再利用可能なページでもっとも注目するべきカテゴリは、ページキャッシュとanonymous memoryです。
.
In most cases, the pages holding internal kernel data and used as DMA buffers cannot be repurposed, and they remain pinned until freed by their user. Such pages are called
unreclaimable
.
多くの場合、カーネル内部データは保持され、DMA bufferとして使うページは転用できず、ユーザーによって解放されるまで固定されます。そのようなページはunreclaimable
と呼ばれます。
However, in certain circumstances, even pages occupied with kernel data structures can be reclaimed.
しかし、特定上農研においては、カーネルデータ構造で占められているページでさえ再利用可能です。
For instance, in-memory caches of filesystem metadata can be re-read from the storage device and therefore it is possible to discard them from the main memory when system is under memory pressure.
例えば、ファイルシステムメタデータのインメモリキャッシュは、ストレージデバイスから再度読み取ることができます。システムがメモリ不足の時に、メインメモリからそれらを開放することができます。
.
The process of freeing the reclaimable physical memory pages and repurposing them is called (surprise!)
reclaim
.
再利用可能な物理メモリページを開放し、再利用するプロセスを(なんと!)"reclaim"と呼びます。
Linux can reclaim pages either asynchronously or synchronously, depending on the state of the system.
Linuxでは、システムの状態に応じて、同期的にあるいは非同期的に、ページを再利用します。
When the system is not loaded, most of the memory is free and allocation requests will be satisfied immediately from the free pages supply.
システム負荷が低い場合、メモリの大半は解放されており、割り当て要求は秋ページから順番に実行されます。
As the load increases, the amount of the free pages goes down and when it reaches a certain threshold (high watermark), an allocation request will awaken the
kswapd
daemon.
負荷が増大すると、秋ページ量が減少します。一定の閾値(high watermark)に到達すると、割り当て要求がkswapd
daemonを呼び起こします。
It will asynchronously scan memory pages and either just free them if the data they contain is available elsewhere, or evict to the backing storage device (remember those dirty pages?).
非同期にメモリページをスキャンし、それらに含まれるデータが他の場所で再利用可能な場合解放するか、backing storage deviceに追い出します(Dirty pageを思い出してください)。
As memory usage increases even more and reaches another threshold - min watermark - an allocation will trigger
direct reclaim
.
メモリ使用量がさらに増加し、別の閾値 ( min watermark) に達すると、割り当てから、"direct reclaim"がトリガーされます。
In this case allocation is stalled until enough memory pages are reclaimed to satisfy the request.
この場合、要求を満たすのに十分なメモリページが回収されるまで、割り当てが停止します。
Compaction
As the system runs, tasks allocate and free the memory and it becomes fragmented.
システムを動かすと、メモリの確保と解放が行われ、フラグメントになる。
Although with virtual memory it is possible to present scattered physical pages as virtually contiguous range, sometimes it is necessary to allocate large physically contiguous memory areas.
仮想メモリによって、物理ページを寄せ集めて、仮想的に連続した範囲を作る事ができる。ただ、時として、物理的に連続的なメモリ範囲を割り当てる必要がある場合もある。
Such need may arise, for instance, when a device driver requires a large buffer for DMA, or when THP allocates a huge page.
例えば、デバイスドライバ―がDMAのために大きなバッファを必要とする、あるいは、THP allocatorがhuge pageを確保する場合、このような要求が発生します。
Memory
compaction
addresses the fragmentation issue.
メモリのcompaction
は、フラグメント問題に対処します。
This mechanism moves occupied pages from the lower part of a memory zone to free pages in the upper part of the zone.
このメカニズムは、占有されているページをメモリゾーンの下位から、メモリゾーン上位の空いている部分に異動させます。
When a compaction scan is finished free pages are grouped together at the beginning of the zone and allocations of large physically contiguous areas become possible.
compaction scanが終わると、空きメモリはzoneの最初にグループ化され、物理的に連続した大きな領域を割り当てることができます。
.
Like reclaim, the compaction may happen asynchronously in the
kcompactd
daemon or synchronously as a result of a memory allocation request.
reclaimと同様に、compactionはkcompactd
daemonによって非同期に、あるいは、メモリ割り当て時の結果として同期して発生することがあります。
OOM killer
It is possible that on a loaded machine memory will be exhausted and the kernel will be unable to reclaim enough memory to continue to operate.
負荷の高いマシンではメモリ使い果たるおそれがあります。それにより、カーネルが動作継続に十分なメモリを改修できない可能性がありまsう。
In order to save the rest of the system, it invokes the
OOM killer
.
システムの残り部分を保存するために、OOM killer
が呼び出されます。
.
The
OOM killer
selects a task to sacrifice for the sake of the overall system health.
OOM killer
は、システム全体の健全性のために、犠牲にするタスクを選択します。
The selected task is killed in a hope that after it exits enough memory will be freed to continue normal operation.
終了した後に通常の操作を続行するために十分なメモリを解放することを期待して、選択したタスクが強制終了されます。