← Documents Documentation/mm/page_migration.rst GitHub 원문 ↗

Linux 6.18.37 · Memory management

Page migration

NUMA page migration interface, migrate_pages() 내부 절차, movable_ops와 monitor counter를 설명합니다.

Source pathDocumentation/mm/page_migration.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

page_migration.rst:1-207

Page migration은 virtual address를 유지하면서 physical page를 NUMA node 사이에서 옮겨 locality를 개선합니다. Kernel은 folio를 LRU에서 isolate하고 page-table reference를 migration entry로 바꾼 뒤 mapping, content, flag, PTE와 LRU membership을 새 page로 단계적으로 이전합니다.

Page migration 상위 흐름
Folio를 LRU에서 isolateNew folio 할당Old·new page lockPTE를 migration entry로 전환Mapping을 new page로 변경Content·flag 복사실제 PTE 복원New page를 LRU에 복귀

접근을 잠시 막고 mapping과 내용을 destination page로 안전하게 옮깁니다.

Userspace locality 조정
`/proc/<pid>/numa_maps`Remote page 확인`mbind` / `migrate_pages` / `move_pages`가까운 NUMA node
Cpuset 변경Task 이동Page 함께 이동Allocation pattern 보존

Scheduler 또는 profiler가 발견한 remote access를 migration interface로 고칩니다.

Migration monitor counter
Counter의미단위
`PGMIGRATE_SUCCESS`일반 migration 성공Base page 또는 THP·hugetlb subpage 수
`PGMIGRATE_FAIL`일반 migration 실패Base page 또는 THP·hugetlb subpage 수
`THP_MIGRATION_SUCCESS`Split 없이 THP 이동THP event
`THP_MIGRATION_FAIL`이동과 split 모두 실패THP event
`THP_MIGRATION_SPLIT`Split 후 subpage 재시도THP event

THP event는 일반 PGMIGRATE counter도 함께 갱신합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ==============
2 Page migration
3 ==============
4
5 Page migration allows moving the physical location of pages between
6 nodes in a NUMA system while the process is running. This means that the
7 virtual addresses that the process sees do not change. However, the
8 system rearranges the physical location of those pages.
9
10 Also see Documentation/mm/hmm.rst for migrating pages to or from device
11 private memory.
12
13 The main intent of page migration is to reduce the latency of memory accesses
14 by moving pages near to the processor where the process accessing that memory
15 is running.
16
17 Page migration allows a process to manually relocate the node on which its
18 pages are located through the MF_MOVE and MF_MOVE_ALL options while setting
19 a new memory policy via mbind(). The pages of a process can also be relocated
20 from another process using the sys_migrate_pages() function call. The
21 migrate_pages() function call takes two sets of nodes and moves pages of a
22 process that are located on the from nodes to the destination nodes.
23 Page migration functions are provided by the numactl package by Andi Kleen
24 (a version later than 0.9.3 is required. Get it from
25 https://github.com/numactl/numactl.git). numactl provides libnuma
26 which provides an interface similar to other NUMA functionality for page
27 migration. cat ``/proc/<pid>/numa_maps`` allows an easy review of where the
28 pages of a process are located. See also the numa_maps documentation in the
29 proc(5) man page.
30
31 Manual migration is useful if for example the scheduler has relocated
32 a process to a processor on a distant node. A batch scheduler or an
33 administrator may detect the situation and move the pages of the process
34 nearer to the new processor. The kernel itself only provides
35 manual page migration support. Automatic page migration may be implemented
36 through user space processes that move pages. A special function call
37 "move_pages" allows the moving of individual pages within a process.
38 For example, A NUMA profiler may obtain a log showing frequent off-node
39 accesses and may use the result to move pages to more advantageous
40 locations.
41
42 Larger installations usually partition the system using cpusets into
43 sections of nodes. Paul Jackson has equipped cpusets with the ability to
44 move pages when a task is moved to another cpuset (See
45 :ref:`CPUSETS <cpusets>`).
46 Cpusets allow the automation of process locality. If a task is moved to
47 a new cpuset then also all its pages are moved with it so that the
48 performance of the process does not sink dramatically. Also the pages
49 of processes in a cpuset are moved if the allowed memory nodes of a
50 cpuset are changed.
51
52 Page migration allows the preservation of the relative location of pages
53 within a group of nodes for all migration techniques which will preserve a
54 particular memory allocation pattern generated even after migrating a
55 process. This is necessary in order to preserve the memory latencies.
56 Processes will run with similar performance after migration.
57
58 Page migration occurs in several steps. First a high level
59 description for those trying to use migrate_pages() from the kernel
60 (for userspace usage see the Andi Kleen's numactl package mentioned above)
61 and then a low level description of how the low level details work.
62
63 In kernel use of migrate_pages()
64 ================================
65
66 1. Remove folios from the LRU.
67
68 Lists of folios to be migrated are generated by scanning over
69 folios and moving them into lists. This is done by
70 calling folio_isolate_lru().
71 Calling folio_isolate_lru() increases the references to the folio
72 so that it cannot vanish while the folio migration occurs.
73 It also prevents the swapper or other scans from encountering
74 the folio.
75
76 2. We need to have a function of type new_folio_t that can be
77 passed to migrate_pages(). This function should figure out
78 how to allocate the correct new folio given the old folio.
79
80 3. The migrate_pages() function is called which attempts
81 to do the migration. It will call the function to allocate
82 the new folio for each folio that is considered for moving.
83
84 How migrate_pages() works
85 =========================
86
87 migrate_pages() does several passes over its list of folios. A folio is moved
88 if all references to a folio are removable at the time. The folio has
89 already been removed from the LRU via folio_isolate_lru() and the refcount
90 is increased so that the folio cannot be freed while folio migration occurs.
91
92 Steps:
93
94 1. Lock the page to be migrated.
95
96 2. Ensure that writeback is complete.
97
98 3. Lock the new page that we want to move to. It is locked so that accesses to
99 this (not yet up-to-date) page immediately block while the move is in progress.
100
101 4. All the page table references to the page are converted to migration
102 entries. This decreases the mapcount of a page. If the resulting
103 mapcount is not zero then we do not migrate the page. All user space
104 processes that attempt to access the page will now wait on the page lock
105 or wait for the migration page table entry to be removed.
106
107 5. The i_pages lock is taken. This will cause all processes trying
108 to access the page via the mapping to block on the spinlock.
109
110 6. The refcount of the page is examined and we back out if references remain.
111 Otherwise, we know that we are the only one referencing this page.
112
113 7. The radix tree is checked and if it does not contain the pointer to this
114 page then we back out because someone else modified the radix tree.
115
116 8. The new page is prepped with some settings from the old page so that
117 accesses to the new page will discover a page with the correct settings.
118
119 9. The radix tree is changed to point to the new page.
120
121 10. The reference count of the old page is dropped because the address space
122 reference is gone. A reference to the new page is established because
123 the new page is referenced by the address space.
124
125 11. The i_pages lock is dropped. With that lookups in the mapping
126 become possible again. Processes will move from spinning on the lock
127 to sleeping on the locked new page.
128
129 12. The page contents are copied to the new page.
130
131 13. The remaining page flags are copied to the new page.
132
133 14. The old page flags are cleared to indicate that the page does
134 not provide any information anymore.
135
136 15. Queued up writeback on the new page is triggered.
137
138 16. If migration entries were inserted into the page table, then replace them
139 with real ptes. Doing so will enable access for user space processes not
140 already waiting for the page lock.
141
142 17. The page locks are dropped from the old and new page.
143 Processes waiting on the page lock will redo their page faults
144 and will reach the new page.
145
146 18. The new page is moved to the LRU and can be scanned by the swapper,
147 etc. again.
148
149 movable_ops page migration
150 ==========================
151
152 Selected typed, non-folio pages (e.g., pages inflated in a memory balloon,
153 zsmalloc pages) can be migrated using the movable_ops migration framework.
154
155 The "struct movable_operations" provide callbacks specific to a page type
156 for isolating, migrating and un-isolating (putback) these pages.
157
158 Once a page is indicated as having movable_ops, that condition must not
159 change until the page was freed back to the buddy. This includes not
160 changing/clearing the page type and not changing/clearing the
161 PG_movable_ops page flag.
162
163 Arbitrary drivers cannot currently make use of this framework, as it
164 requires:
165
166 (a) a page type
167 (b) indicating them as possibly having movable_ops in page_has_movable_ops()
168 based on the page type
169 (c) returning the movable_ops from page_movable_ops() based on the page
170 type
171 (d) not reusing the PG_movable_ops and PG_movable_ops_isolated page flags
172 for other purposes
173
174 For example, balloon drivers can make use of this framework through the
175 balloon-compaction infrastructure residing in the core kernel.
176
177 Monitoring Migration
178 =====================
179
180 The following events (counters) can be used to monitor page migration.
181
182 1. PGMIGRATE_SUCCESS: Normal page migration success. Each count means that a
183 page was migrated. If the page was a non-THP and non-hugetlb page, then
184 this counter is increased by one. If the page was a THP or hugetlb, then
185 this counter is increased by the number of THP or hugetlb subpages.
186 For example, migration of a single 2MB THP that has 4KB-size base pages
187 (subpages) will cause this counter to increase by 512.
188
189 2. PGMIGRATE_FAIL: Normal page migration failure. Same counting rules as for
190 PGMIGRATE_SUCCESS, above: this will be increased by the number of subpages,
191 if it was a THP or hugetlb.
192
193 3. THP_MIGRATION_SUCCESS: A THP was migrated without being split.
194
195 4. THP_MIGRATION_FAIL: A THP could not be migrated nor it could be split.
196
197 5. THP_MIGRATION_SPLIT: A THP was migrated, but not as such: first, the THP had
198 to be split. After splitting, a migration retry was used for its sub-pages.
199
200 THP_MIGRATION_* events also update the appropriate PGMIGRATE_SUCCESS or
201 PGMIGRATE_FAIL events. For example, a THP migration failure will cause both
202 THP_MIGRATION_FAIL and PGMIGRATE_FAIL to increase.
203
204 Christoph Lameter, May 8, 2006.
205 Minchan Kim, Mar 28, 2016.
206
207 .. kernel-doc:: include/linux/migrate.h
208

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Page migration의 목적

1-15

Page migration은 process가 실행되는 동안 NUMA system의 node 사이에서 page의 physical 위치를 옮깁니다. Process가 보는 virtual address는 바뀌지 않지만 system이 page의 physical 위치를 다시 배치합니다.

Device-private memory로 page를 보내거나 가져오는 migration은 `Documentation/mm/hmm.rst`도 참조하십시오.

주된 목적은 memory에 접근하는 process가 실행 중인 processor 가까이로 page를 옮겨 memory-access latency를 줄이는 것입니다.

==============
Page migration
==============

Page migration allows moving the physical location of pages between
nodes in a NUMA system while the process is running. This means that the
virtual addresses that the process sees do not change. However, the
system rearranges the physical location of those pages.

Also see Documentation/mm/hmm.rst for migrating pages to or from device
private memory.

The main intent of page migration is to reduce the latency of memory accesses
by moving pages near to the processor where the process accessing that memory
is running.

User interface와 수동 migration

16-40

Process는 `mbind()`로 새 memory policy를 설정하면서 `MF_MOVE` 또는 `MF_MOVE_ALL` option을 사용해 page가 있는 node를 직접 바꿀 수 있습니다. 다른 process의 page는 `sys_migrate_pages()` system call로 옮길 수 있습니다. `migrate_pages()`는 출발 node set과 destination node set을 받아 출발 node에 있는 process page를 destination node로 이동합니다.

Page-migration 함수는 Andi Kleen의 `numactl` package가 제공합니다. 0.9.3보다 새 version이 필요하며 source는 `https://github.com/numactl/numactl.git`에 있습니다. `numactl`의 `libnuma`는 다른 NUMA 기능과 비슷한 page-migration interface를 제공합니다. `cat /proc/<pid>/numa_maps`로 process page의 위치를 쉽게 살펴볼 수 있고, `proc(5)` man page의 `numa_maps` 문서도 참고할 수 있습니다.

Scheduler가 process를 먼 node의 processor로 옮긴 경우 수동 migration이 유용합니다. Batch scheduler나 administrator가 이를 감지해 process page를 새 processor 가까이 옮길 수 있습니다. Kernel 자체는 수동 page migration만 제공합니다. 자동 migration은 page를 옮기는 userspace process로 구현할 수 있습니다.

`move_pages`라는 특별한 function call은 process 안의 개별 page를 이동합니다. 예를 들어 NUMA profiler가 잦은 off-node access를 기록하고, 그 결과를 이용해 page를 더 유리한 위치로 옮길 수 있습니다.


Page migration allows a process to manually relocate the node on which its
pages are located through the MF_MOVE and MF_MOVE_ALL options while setting
a new memory policy via mbind(). The pages of a process can also be relocated
from another process using the sys_migrate_pages() function call. The
migrate_pages() function call takes two sets of nodes and moves pages of a
process that are located on the from nodes to the destination nodes.
Page migration functions are provided by the numactl package by Andi Kleen
(a version later than 0.9.3 is required. Get it from
https://github.com/numactl/numactl.git). numactl provides libnuma
which provides an interface similar to other NUMA functionality for page
migration.  cat ``/proc/<pid>/numa_maps`` allows an easy review of where the
pages of a process are located. See also the numa_maps documentation in the
proc(5) man page.

Manual migration is useful if for example the scheduler has relocated
a process to a processor on a distant node. A batch scheduler or an
administrator may detect the situation and move the pages of the process
nearer to the new processor. The kernel itself only provides
manual page migration support. Automatic page migration may be implemented
through user space processes that move pages. A special function call
"move_pages" allows the moving of individual pages within a process.
For example, A NUMA profiler may obtain a log showing frequent off-node
accesses and may use the result to move pages to more advantageous
locations.

Cpuset과 배치 pattern 보존

41-62

대규모 system은 보통 cpuset을 이용해 node를 여러 구역으로 나눕니다. Paul Jackson은 task를 다른 cpuset으로 옮길 때 page도 이동하는 기능을 cpuset에 추가했습니다. `CPUSETS` reference를 참조하십시오.

Cpuset은 process locality를 자동화합니다. Task가 새 cpuset으로 이동하면 모든 page도 함께 옮겨 process 성능이 크게 떨어지는 것을 막습니다. Cpuset에서 허용하는 memory node가 바뀌어도 그 cpuset process의 page를 이동합니다.

모든 migration 기법은 node group 안에서 page의 상대 위치를 보존할 수 있습니다. 따라서 process를 옮긴 뒤에도 원래 생성된 memory-allocation pattern과 memory latency를 유지해 비슷한 성능으로 실행할 수 있습니다.

이하에서는 먼저 kernel에서 `migrate_pages()`를 사용하는 상위 수준 절차를 설명하고, 이어서 내부 동작을 낮은 수준에서 설명합니다. Userspace 사용법은 앞서 언급한 Andi Kleen의 `numactl` package를 참조하십시오.


Larger installations usually partition the system using cpusets into
sections of nodes. Paul Jackson has equipped cpusets with the ability to
move pages when a task is moved to another cpuset (See
:ref:`CPUSETS <cpusets>`).
Cpusets allow the automation of process locality. If a task is moved to
a new cpuset then also all its pages are moved with it so that the
performance of the process does not sink dramatically. Also the pages
of processes in a cpuset are moved if the allowed memory nodes of a
cpuset are changed.

Page migration allows the preservation of the relative location of pages
within a group of nodes for all migration techniques which will preserve a
particular memory allocation pattern generated even after migrating a
process. This is necessary in order to preserve the memory latencies.
Processes will run with similar performance after migration.

Page migration occurs in several steps. First a high level
description for those trying to use migrate_pages() from the kernel
(for userspace usage see the Andi Kleen's numactl package mentioned above)
and then a low level description of how the low level details work.

Kernel에서 migrate_pages() 사용

63-83
  • 1. Migration할 folio를 LRU에서 제거합니다. Folio를 scan해 list로 옮기고 `folio_isolate_lru()`를 호출합니다. 이 함수는 migration 중 folio가 사라지지 않도록 reference를 늘리고 swapper나 다른 scan이 folio를 만나지 못하게 합니다.
  • 2. `migrate_pages()`에 넘길 `new_folio_t` 유형 함수가 필요합니다. 이 함수는 old folio를 바탕으로 올바른 new folio를 할당하는 방법을 결정해야 합니다.
  • 3. `migrate_pages()`를 호출해 migration을 시도합니다. 이동 대상으로 검토하는 folio마다 앞의 함수를 호출해 new folio를 할당합니다.
In kernel use of migrate_pages()
================================

1. Remove folios from the LRU.

   Lists of folios to be migrated are generated by scanning over
   folios and moving them into lists. This is done by
   calling folio_isolate_lru().
   Calling folio_isolate_lru() increases the references to the folio
   so that it cannot vanish while the folio migration occurs.
   It also prevents the swapper or other scans from encountering
   the folio.

2. We need to have a function of type new_folio_t that can be
   passed to migrate_pages(). This function should figure out
   how to allocate the correct new folio given the old folio.

3. The migrate_pages() function is called which attempts
   to do the migration. It will call the function to allocate
   the new folio for each folio that is considered for moving.

migrate_pages() 내부 18단계

84-148

`migrate_pages()`는 folio list를 여러 번 순회합니다. 해당 시점에 folio의 모든 reference를 제거할 수 있을 때 folio를 옮깁니다. Folio는 이미 `folio_isolate_lru()`로 LRU에서 빠져 있고, migration 중 free되지 않도록 refcount가 증가한 상태입니다.

  • 1. Migration할 old page를 lock합니다.
  • 2. Writeback이 끝났는지 확인합니다.
  • 3. Destination인 new page를 lock합니다. 아직 up-to-date가 아닌 이 page에 접근하면 이동이 끝날 때까지 즉시 block됩니다.
  • 4. Old page를 가리키는 모든 page-table reference를 migration entry로 바꿉니다. Page mapcount가 감소하며, 결과가 0이 아니면 migration하지 않습니다. Page에 접근하는 userspace process는 page lock 또는 migration entry 제거를 기다립니다.
  • 5. `i_pages` lock을 잡아 mapping을 통해 page에 접근하려는 모든 process가 spinlock에서 block되게 합니다.
  • 6. Page refcount를 검사합니다. 남은 reference가 있으면 작업을 되돌립니다. 없다면 현재 migration code만 page를 참조한다는 뜻입니다.
  • 7. Radix tree가 old page pointer를 담고 있는지 검사합니다. 없다면 다른 주체가 radix tree를 바꾼 것이므로 되돌립니다.
  • 8. Old page 설정 일부를 new page에 준비해, new page 접근자가 올바른 설정을 발견하게 합니다.
  • 9. Radix tree가 new page를 가리키도록 바꿉니다.
  • 10. Address-space reference가 사라졌으므로 old page reference count를 줄이고, address space가 new page를 참조하므로 new page reference를 설정합니다.
  • 11. `i_pages` lock을 놓습니다. Mapping lookup이 다시 가능해지고 process는 lock에서 spin하던 상태에서 locked new page를 기다리는 sleep 상태로 넘어갑니다.
  • 12. Old page 내용을 new page로 복사합니다.
  • 13. 남은 page flag를 new page로 복사합니다.
  • 14. Old page가 더는 정보를 제공하지 않음을 나타내도록 old page flag를 지웁니다.
  • 15. New page에 대기 중이던 writeback을 시작합니다.
  • 16. Page table에 migration entry를 넣었다면 이를 실제 PTE로 교체합니다. Page lock을 이미 기다리지 않는 userspace process도 다시 접근할 수 있게 됩니다.
  • 17. Old page와 new page의 lock을 놓습니다. Page lock을 기다리던 process는 page fault를 다시 수행해 new page에 도달합니다.
  • 18. New page를 LRU로 옮깁니다. 이제 swapper 등의 scan 대상이 될 수 있습니다.
How migrate_pages() works
=========================

migrate_pages() does several passes over its list of folios. A folio is moved
if all references to a folio are removable at the time. The folio has
already been removed from the LRU via folio_isolate_lru() and the refcount
is increased so that the folio cannot be freed while folio migration occurs.

Steps:

1. Lock the page to be migrated.

2. Ensure that writeback is complete.

3. Lock the new page that we want to move to. It is locked so that accesses to
   this (not yet up-to-date) page immediately block while the move is in progress.

4. All the page table references to the page are converted to migration
   entries. This decreases the mapcount of a page. If the resulting
   mapcount is not zero then we do not migrate the page. All user space
   processes that attempt to access the page will now wait on the page lock
   or wait for the migration page table entry to be removed.

5. The i_pages lock is taken. This will cause all processes trying
   to access the page via the mapping to block on the spinlock.

6. The refcount of the page is examined and we back out if references remain.
   Otherwise, we know that we are the only one referencing this page.

7. The radix tree is checked and if it does not contain the pointer to this
   page then we back out because someone else modified the radix tree.

8. The new page is prepped with some settings from the old page so that
   accesses to the new page will discover a page with the correct settings.

9. The radix tree is changed to point to the new page.

10. The reference count of the old page is dropped because the address space
    reference is gone. A reference to the new page is established because
    the new page is referenced by the address space.

11. The i_pages lock is dropped. With that lookups in the mapping
    become possible again. Processes will move from spinning on the lock
    to sleeping on the locked new page.

12. The page contents are copied to the new page.

13. The remaining page flags are copied to the new page.

14. The old page flags are cleared to indicate that the page does
    not provide any information anymore.

15. Queued up writeback on the new page is triggered.

16. If migration entries were inserted into the page table, then replace them
    with real ptes. Doing so will enable access for user space processes not
    already waiting for the page lock.

17. The page locks are dropped from the old and new page.
    Processes waiting on the page lock will redo their page faults
    and will reach the new page.

18. The new page is moved to the LRU and can be scanned by the swapper,
    etc. again.

movable_ops page migration

149-176

Memory balloon에서 inflate된 page나 zsmalloc page처럼 유형이 지정된 일부 non-folio page는 `movable_ops` migration framework로 옮길 수 있습니다. `struct movable_operations`는 이런 page를 isolate, migrate, un-isolate 또는 putback하기 위한 page-type별 callback을 제공합니다.

Page가 `movable_ops`를 가진다고 표시되면 buddy allocator로 free될 때까지 그 상태를 바꾸면 안 됩니다. Page type을 변경하거나 지우는 것과 `PG_movable_ops` page flag를 변경하거나 지우는 것 모두 금지됩니다.

임의의 driver는 현재 이 framework를 바로 사용할 수 없습니다. 다음 조건이 필요합니다.

  • a. Page type이 있어야 합니다.
  • b. Page type에 근거해 `page_has_movable_ops()`에서 해당 page가 `movable_ops`를 가질 수 있다고 표시해야 합니다.
  • c. Page type에 근거해 `page_movable_ops()`가 `movable_ops`를 반환해야 합니다.
  • d. `PG_movable_ops`와 `PG_movable_ops_isolated` page flag를 다른 목적으로 재사용하면 안 됩니다.

예를 들어 balloon driver는 core kernel의 balloon-compaction infrastructure를 통해 이 framework를 사용할 수 있습니다.

movable_ops page migration
==========================

Selected typed, non-folio pages (e.g., pages inflated in a memory balloon,
zsmalloc pages) can be migrated using the movable_ops migration framework.

The "struct movable_operations" provide callbacks specific to a page type
for isolating, migrating and un-isolating (putback) these pages.

Once a page is indicated as having movable_ops, that condition must not
change until the page was freed back to the buddy. This includes not
changing/clearing the page type and not changing/clearing the
PG_movable_ops page flag.

Arbitrary drivers cannot currently make use of this framework, as it
requires:

(a) a page type
(b) indicating them as possibly having movable_ops in page_has_movable_ops()
    based on the page type
(c) returning the movable_ops from page_movable_ops() based on the page
    type
(d) not reusing the PG_movable_ops and PG_movable_ops_isolated page flags
    for other purposes

For example, balloon drivers can make use of this framework through the
balloon-compaction infrastructure residing in the core kernel.

Migration monitor counter

177-207

다음 event counter로 page migration을 monitor할 수 있습니다.

  • `PGMIGRATE_SUCCESS`: 일반 page migration 성공입니다. Non-THP이면서 non-hugetlb인 page는 migration된 page마다 1 증가합니다. THP 또는 hugetlb이면 subpage 수만큼 증가합니다. 4KB base page로 구성된 2MB THP 하나를 옮기면 512 증가합니다.
  • `PGMIGRATE_FAIL`: 일반 page migration 실패입니다. `PGMIGRATE_SUCCESS`와 같은 규칙으로 세며, THP 또는 hugetlb이면 subpage 수만큼 증가합니다.
  • `THP_MIGRATION_SUCCESS`: THP를 split하지 않고 옮겼습니다.
  • `THP_MIGRATION_FAIL`: THP를 옮기지도 split하지도 못했습니다.
  • `THP_MIGRATION_SPLIT`: THP 자체로는 옮기지 못해 먼저 split한 뒤 subpage migration을 재시도했습니다.

`THP_MIGRATION_*` event는 알맞은 `PGMIGRATE_SUCCESS` 또는 `PGMIGRATE_FAIL`도 함께 갱신합니다. 예를 들어 THP migration 실패는 `THP_MIGRATION_FAIL`과 `PGMIGRATE_FAIL`을 모두 증가시킵니다.

Christoph Lameter가 2006년 5월 8일, Minchan Kim이 2016년 3월 28일 작성했습니다. 마지막 kernel-doc directive는 `include/linux/migrate.h`를 포함합니다.

Monitoring Migration
=====================

The following events (counters) can be used to monitor page migration.

1. PGMIGRATE_SUCCESS: Normal page migration success. Each count means that a
   page was migrated. If the page was a non-THP and non-hugetlb page, then
   this counter is increased by one. If the page was a THP or hugetlb, then
   this counter is increased by the number of THP or hugetlb subpages.
   For example, migration of a single 2MB THP that has 4KB-size base pages
   (subpages) will cause this counter to increase by 512.

2. PGMIGRATE_FAIL: Normal page migration failure. Same counting rules as for
   PGMIGRATE_SUCCESS, above: this will be increased by the number of subpages,
   if it was a THP or hugetlb.

3. THP_MIGRATION_SUCCESS: A THP was migrated without being split.

4. THP_MIGRATION_FAIL: A THP could not be migrated nor it could be split.

5. THP_MIGRATION_SPLIT: A THP was migrated, but not as such: first, the THP had
   to be split. After splitting, a migration retry was used for its sub-pages.

THP_MIGRATION_* events also update the appropriate PGMIGRATE_SUCCESS or
PGMIGRATE_FAIL events. For example, a THP migration failure will cause both
THP_MIGRATION_FAIL and PGMIGRATE_FAIL to increase.

Christoph Lameter, May 8, 2006.
Minchan Kim, Mar 28, 2016.

.. kernel-doc:: include/linux/migrate.h