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

Linux 6.18.37 · Memory management

page owner: Tracking about who allocated each page

Page allocation stack을 수집하고 page_owner_sort로 memory 사용처를 정렬·병합·필터하는 방법을 설명합니다.

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

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

1. 요약·해설

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

요약·해설

page_owner.rst:1-235

Page owner는 page별 allocation stack, order와 allocator 정보를 보존해 memory leak과 큰 allocation source를 찾습니다. Stack별 base-page 수를 빠르게 보거나 전체 PFN dump를 `page_owner_sort`로 정렬·병합·필터할 수 있습니다.

Page owner 분석 흐름
`page_owner=on`으로 bootWorkload 실행`show_stacks` 또는 전체 `page_owner` dump`count_threshold` 적용`page_owner_sort`할당자·stack·memory 규모 확인

Boot-time 수집부터 stack 요약 또는 전체 dump 분석까지의 경로입니다.

page_owner_sort 제어 축
기능Option역할
Sort`-a -m -p -P -n -r -s -t`, `--sort`Block 출력 순서 결정
Cull`--cull`선택 key가 같은 block 병합
Filter`-f`Release된 block 제외
Select`--pid`, `--tgid`, `--name`지정 process·group·command만 선택

정렬, cull, filter와 select가 서로 다른 분석 단계를 담당합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 ==================================================
2 page owner: Tracking about who allocated each page
3 ==================================================
4
5 Introduction
6 ============
7
8 page owner is for the tracking about who allocated each page.
9 It can be used to debug memory leak or to find a memory hogger.
10 When allocation happens, information about allocation such as call stack
11 and order of pages is stored into certain storage for each page.
12 When we need to know about status of all pages, we can get and analyze
13 this information.
14
15 Although we already have tracepoint for tracing page allocation/free,
16 using it for analyzing who allocate each page is rather complex. We need
17 to enlarge the trace buffer for preventing overlapping until userspace
18 program launched. And, launched program continually dump out the trace
19 buffer for later analysis and it would change system behaviour with more
20 possibility rather than just keeping it in memory, so bad for debugging.
21
22 page owner can also be used for various purposes. For example, accurate
23 fragmentation statistics can be obtained through gfp flag information of
24 each page. It is already implemented and activated if page owner is
25 enabled. Other usages are more than welcome.
26
27 It can also be used to show all the stacks and their current number of
28 allocated base pages, which gives us a quick overview of where the memory
29 is going without the need to screen through all the pages and match the
30 allocation and free operation.
31
32 page owner is disabled by default. So, if you'd like to use it, you need
33 to add "page_owner=on" to your boot cmdline. If the kernel is built
34 with page owner and page owner is disabled in runtime due to not enabling
35 boot option, runtime overhead is marginal. If disabled in runtime, it
36 doesn't require memory to store owner information, so there is no runtime
37 memory overhead. And, page owner inserts just two unlikely branches into
38 the page allocator hotpath and if not enabled, then allocation is done
39 like as the kernel without page owner. These two unlikely branches should
40 not affect to allocation performance, especially if the static keys jump
41 label patching functionality is available. Following is the kernel's code
42 size change due to this facility.
43
44 Although enabling page owner increases kernel size by several kilobytes,
45 most of this code is outside page allocator and its hot path. Building
46 the kernel with page owner and turning it on if needed would be great
47 option to debug kernel memory problem.
48
49 There is one notice that is caused by implementation detail. page owner
50 stores information into the memory from struct page extension. This memory
51 is initialized some time later than that page allocator starts in sparse
52 memory system, so, until initialization, many pages can be allocated and
53 they would have no owner information. To fix it up, these early allocated
54 pages are investigated and marked as allocated in initialization phase.
55 Although it doesn't mean that they have the right owner information,
56 at least, we can tell whether the page is allocated or not,
57 more accurately. On 2GB memory x86-64 VM box, 13343 early allocated pages
58 are caught and marked, although they are mostly allocated from struct
59 page extension feature. Anyway, after that, no page is left in
60 un-tracking state.
61
62 Usage
63 =====
64
65 1) Build user-space helper::
66
67 cd tools/mm
68 make page_owner_sort
69
70 2) Enable page owner: add "page_owner=on" to boot cmdline.
71
72 3) Do the job that you want to debug.
73
74 4) Analyze information from page owner::
75
76 cat /sys/kernel/debug/page_owner_stacks/show_stacks > stacks.txt
77 cat stacks.txt
78 post_alloc_hook+0x177/0x1a0
79 get_page_from_freelist+0xd01/0xd80
80 __alloc_pages+0x39e/0x7e0
81 allocate_slab+0xbc/0x3f0
82 ___slab_alloc+0x528/0x8a0
83 kmem_cache_alloc+0x224/0x3b0
84 sk_prot_alloc+0x58/0x1a0
85 sk_alloc+0x32/0x4f0
86 inet_create+0x427/0xb50
87 __sock_create+0x2e4/0x650
88 inet_ctl_sock_create+0x30/0x180
89 igmp_net_init+0xc1/0x130
90 ops_init+0x167/0x410
91 setup_net+0x304/0xa60
92 copy_net_ns+0x29b/0x4a0
93 create_new_namespaces+0x4a1/0x820
94 nr_base_pages: 16
95 ...
96 ...
97 echo 7000 > /sys/kernel/debug/page_owner_stacks/count_threshold
98 cat /sys/kernel/debug/page_owner_stacks/show_stacks> stacks_7000.txt
99 cat stacks_7000.txt
100 post_alloc_hook+0x177/0x1a0
101 get_page_from_freelist+0xd01/0xd80
102 __alloc_pages+0x39e/0x7e0
103 alloc_pages_mpol+0x22e/0x490
104 folio_alloc+0xd5/0x110
105 filemap_alloc_folio+0x78/0x230
106 page_cache_ra_order+0x287/0x6f0
107 filemap_get_pages+0x517/0x1160
108 filemap_read+0x304/0x9f0
109 xfs_file_buffered_read+0xe6/0x1d0 [xfs]
110 xfs_file_read_iter+0x1f0/0x380 [xfs]
111 __kernel_read+0x3b9/0x730
112 kernel_read_file+0x309/0x4d0
113 __do_sys_finit_module+0x381/0x730
114 do_syscall_64+0x8d/0x150
115 entry_SYSCALL_64_after_hwframe+0x62/0x6a
116 nr_base_pages: 20824
117 ...
118
119 cat /sys/kernel/debug/page_owner > page_owner_full.txt
120 ./page_owner_sort page_owner_full.txt sorted_page_owner.txt
121
122 The general output of ``page_owner_full.txt`` is as follows::
123
124 Page allocated via order XXX, ...
125 PFN XXX ...
126 // Detailed stack
127
128 Page allocated via order XXX, ...
129 PFN XXX ...
130 // Detailed stack
131 By default, it will do full pfn dump, to start with a given pfn,
132 page_owner supports fseek.
133
134 FILE *fp = fopen("/sys/kernel/debug/page_owner", "r");
135 fseek(fp, pfn_start, SEEK_SET);
136
137 The ``page_owner_sort`` tool ignores ``PFN`` rows, puts the remaining rows
138 in buf, uses regexp to extract the page order value, counts the times
139 and pages of buf, and finally sorts them according to the parameter(s).
140
141 See the result about who allocated each page
142 in the ``sorted_page_owner.txt``. General output::
143
144 XXX times, XXX pages:
145 Page allocated via order XXX, ...
146 // Detailed stack
147
148 By default, ``page_owner_sort`` is sorted according to the times of buf.
149 If you want to sort by the page nums of buf, use the ``-m`` parameter.
150 The detailed parameters are:
151
152 fundamental function::
153
154 Sort:
155 -a Sort by memory allocation time.
156 -m Sort by total memory.
157 -p Sort by pid.
158 -P Sort by tgid.
159 -n Sort by task command name.
160 -r Sort by memory release time.
161 -s Sort by stack trace.
162 -t Sort by times (default).
163 --sort <order> Specify sorting order. Sorting syntax is [+|-]key[,[+|-]key[,...]].
164 Choose a key from the **STANDARD FORMAT SPECIFIERS** section. The "+" is
165 optional since default direction is increasing numerical or lexicographic
166 order. Mixed use of abbreviated and complete-form of keys is allowed.
167
168 Examples:
169 ./page_owner_sort <input> <output> --sort=n,+pid,-tgid
170 ./page_owner_sort <input> <output> --sort=at
171
172 additional function::
173
174 Cull:
175 --cull <rules>
176 Specify culling rules.Culling syntax is key[,key[,...]].Choose a
177 multi-letter key from the **STANDARD FORMAT SPECIFIERS** section.
178
179 <rules> is a single argument in the form of a comma-separated list,
180 which offers a way to specify individual culling rules. The recognized
181 keywords are described in the **STANDARD FORMAT SPECIFIERS** section below.
182 <rules> can be specified by the sequence of keys k1,k2, ..., as described in
183 the STANDARD SORT KEYS section below. Mixed use of abbreviated and
184 complete-form of keys is allowed.
185
186 Examples:
187 ./page_owner_sort <input> <output> --cull=stacktrace
188 ./page_owner_sort <input> <output> --cull=st,pid,name
189 ./page_owner_sort <input> <output> --cull=n,f
190
191 Filter:
192 -f Filter out the information of blocks whose memory has been released.
193
194 Select:
195 --pid <pidlist> Select by pid. This selects the blocks whose process ID
196 numbers appear in <pidlist>.
197 --tgid <tgidlist> Select by tgid. This selects the blocks whose thread
198 group ID numbers appear in <tgidlist>.
199 --name <cmdlist> Select by task command name. This selects the blocks whose
200 task command name appear in <cmdlist>.
201
202 <pidlist>, <tgidlist>, <cmdlist> are single arguments in the form of a comma-separated list,
203 which offers a way to specify individual selecting rules.
204
205
206 Examples:
207 ./page_owner_sort <input> <output> --pid=1
208 ./page_owner_sort <input> <output> --tgid=1,2,3
209 ./page_owner_sort <input> <output> --name name1,name2
210
211 STANDARD FORMAT SPECIFIERS
212 ==========================
213 ::
214
215 For --sort option:
216
217 KEY LONG DESCRIPTION
218 p pid process ID
219 tg tgid thread group ID
220 n name task command name
221 st stacktrace stack trace of the page allocation
222 T txt full text of block
223 ft free_ts timestamp of the page when it was released
224 at alloc_ts timestamp of the page when it was allocated
225 ator allocator memory allocator for pages
226
227 For --cull option:
228
229 KEY LONG DESCRIPTION
230 p pid process ID
231 tg tgid thread group ID
232 n name task command name
233 f free whether the page has been released or not
234 st stacktrace stack trace of the page allocation
235 ator allocator memory allocator for pages
236

3. 한국어 전문 번역

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

Page owner의 목적

1-30

Page owner는 각 page를 누가 할당했는지 추적합니다. Memory leak을 debug하거나 memory를 과도하게 쓰는 주체를 찾는 데 사용할 수 있습니다. Allocation이 일어날 때 call stack과 page order 같은 정보를 page마다 별도 storage에 저장하고, 전체 page 상태가 필요할 때 이 정보를 가져와 분석합니다.

Page allocation과 free를 추적하는 tracepoint가 이미 있지만, 그것만으로 각 page의 할당자를 분석하기는 복잡합니다. Userspace program이 시작할 때까지 event가 덮어쓰이지 않도록 trace buffer를 키워야 하며, program을 시작한 뒤에도 나중 분석을 위해 buffer를 계속 dump해야 합니다. 이는 정보를 memory에 보관만 하는 것보다 system 동작을 바꿀 가능성이 커 debugging에 불리합니다.

Page owner는 다른 용도에도 쓸 수 있습니다. Page별 GFP flag 정보로 정확한 fragmentation statistic을 구하는 기능은 이미 구현되어 있으며 page owner를 enable하면 활성화됩니다.

현재 각 allocation stack이 보유한 base-page 수를 모두 표시할 수도 있습니다. 모든 page를 훑으며 allocation과 free를 맞추지 않고도 memory가 어디에 쓰이는지 빠르게 파악할 수 있습니다.

==================================================
page owner: Tracking about who allocated each page
==================================================

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

page owner is for the tracking about who allocated each page.
It can be used to debug memory leak or to find a memory hogger.
When allocation happens, information about allocation such as call stack
and order of pages is stored into certain storage for each page.
When we need to know about status of all pages, we can get and analyze
this information.

Although we already have tracepoint for tracing page allocation/free,
using it for analyzing who allocate each page is rather complex. We need
to enlarge the trace buffer for preventing overlapping until userspace
program launched. And, launched program continually dump out the trace
buffer for later analysis and it would change system behaviour with more
possibility rather than just keeping it in memory, so bad for debugging.

page owner can also be used for various purposes. For example, accurate
fragmentation statistics can be obtained through gfp flag information of
each page. It is already implemented and activated if page owner is
enabled. Other usages are more than welcome.

It can also be used to show all the stacks and their current number of
allocated base pages, which gives us a quick overview of where the memory
is going without the need to screen through all the pages and match the
allocation and free operation.

Enable 방법, overhead와 초기 page

31-61

Page owner는 기본적으로 disable되어 있습니다. 사용하려면 boot command line에 `page_owner=on`을 추가해야 합니다. Kernel을 page-owner 지원으로 build했어도 boot option을 주지 않아 runtime에 disable된 상태라면 overhead는 미미합니다.

Runtime에 disable되어 있으면 owner 정보를 저장할 memory가 필요하지 않아 runtime memory overhead가 없습니다. Page allocator hot path에는 실행 가능성이 낮은 branch 두 개만 들어가며, disable 상태의 allocation은 page owner가 없는 kernel과 같습니다. 특히 static-key jump-label patching을 사용할 수 있다면 두 branch가 allocation 성능에 영향을 주지 않아야 합니다.

Page owner를 enable하면 kernel 크기가 수 KB 늘지만 code 대부분은 page allocator와 hot path 밖에 있습니다. 따라서 page-owner 지원으로 kernel을 build해 두고 kernel-memory 문제를 debug할 때 enable하는 방식이 유용합니다.

구현상 주의점이 하나 있습니다. Page owner는 `struct page` extension memory에 정보를 저장합니다. Sparse-memory system에서는 이 memory가 page allocator 시작보다 늦게 초기화되므로, 그 전까지 할당된 많은 page에는 owner 정보가 없습니다.

초기화 단계에서 이 early-allocated page를 조사해 allocated로 표시합니다. 올바른 owner 정보는 아니지만 적어도 allocation 여부는 더 정확히 알 수 있습니다. 2GB memory x86-64 VM에서는 early-allocated page 13,343개를 찾아 표시했으며, 대부분 `struct page` extension 기능이 할당한 page였습니다. 이후에는 추적되지 않은 상태의 page가 남지 않습니다.


page owner is disabled by default. So, if you'd like to use it, you need
to add "page_owner=on" to your boot cmdline. If the kernel is built
with page owner and page owner is disabled in runtime due to not enabling
boot option, runtime overhead is marginal. If disabled in runtime, it
doesn't require memory to store owner information, so there is no runtime
memory overhead. And, page owner inserts just two unlikely branches into
the page allocator hotpath and if not enabled, then allocation is done
like as the kernel without page owner. These two unlikely branches should
not affect to allocation performance, especially if the static keys jump
label patching functionality is available. Following is the kernel's code
size change due to this facility.

Although enabling page owner increases kernel size by several kilobytes,
most of this code is outside page allocator and its hot path. Building
the kernel with page owner and turning it on if needed would be great
option to debug kernel memory problem.

There is one notice that is caused by implementation detail. page owner
stores information into the memory from struct page extension. This memory
is initialized some time later than that page allocator starts in sparse
memory system, so, until initialization, many pages can be allocated and
they would have no owner information. To fix it up, these early allocated
pages are investigated and marked as allocated in initialization phase.
Although it doesn't mean that they have the right owner information,
at least, we can tell whether the page is allocated or not,
more accurately. On 2GB memory x86-64 VM box, 13343 early allocated pages
are caught and marked, although they are mostly allocated from struct
page extension feature. Anyway, after that, no page is left in
un-tracking state.

사용 절차와 stack 분석

62-120

사용 절차는 다음과 같습니다.

  • 1. `tools/mm` directory에서 `make page_owner_sort`를 실행해 userspace helper를 build합니다.
  • 2. Boot command line에 `page_owner=on`을 추가해 page owner를 enable합니다.
  • 3. Debug하려는 workload를 수행합니다.
  • 4. Page-owner 정보를 분석합니다.

`/sys/kernel/debug/page_owner_stacks/show_stacks`를 읽으면 allocation call stack과 현재 할당된 base-page 수인 `nr_base_pages`를 볼 수 있습니다. `count_threshold`에 예를 들어 7000을 쓰면 threshold 이상인 stack만 별도 file로 수집할 수 있습니다.

cat /sys/kernel/debug/page_owner_stacks/show_stacks > stacks.txt
echo 7000 > /sys/kernel/debug/page_owner_stacks/count_threshold
cat /sys/kernel/debug/page_owner_stacks/show_stacks > stacks_7000.txt
cat /sys/kernel/debug/page_owner > page_owner_full.txt
./page_owner_sort page_owner_full.txt sorted_page_owner.txt

첫 예제 stack은 `post_alloc_hook`에서 namespace 생성까지 이어지며 `nr_base_pages: 16`을 보입니다. Threshold 예제의 두 번째 stack은 file readahead와 XFS read path를 거쳐 module load까지 이어지고 `nr_base_pages: 20824`를 보입니다. Function name, offset, module 표기는 원문 code block대로 보존됩니다.

전체 PFN dump는 `/sys/kernel/debug/page_owner`에서 얻고 `page_owner_sort`로 정렬합니다.

Usage
=====

1) Build user-space helper::

        cd tools/mm
        make page_owner_sort

2) Enable page owner: add "page_owner=on" to boot cmdline.

3) Do the job that you want to debug.

4) Analyze information from page owner::

        cat /sys/kernel/debug/page_owner_stacks/show_stacks > stacks.txt
        cat stacks.txt
         post_alloc_hook+0x177/0x1a0
         get_page_from_freelist+0xd01/0xd80
         __alloc_pages+0x39e/0x7e0
         allocate_slab+0xbc/0x3f0
         ___slab_alloc+0x528/0x8a0
         kmem_cache_alloc+0x224/0x3b0
         sk_prot_alloc+0x58/0x1a0
         sk_alloc+0x32/0x4f0
         inet_create+0x427/0xb50
         __sock_create+0x2e4/0x650
         inet_ctl_sock_create+0x30/0x180
         igmp_net_init+0xc1/0x130
         ops_init+0x167/0x410
         setup_net+0x304/0xa60
         copy_net_ns+0x29b/0x4a0
         create_new_namespaces+0x4a1/0x820
        nr_base_pages: 16
        ...
        ...
        echo 7000 > /sys/kernel/debug/page_owner_stacks/count_threshold
        cat /sys/kernel/debug/page_owner_stacks/show_stacks> stacks_7000.txt
        cat stacks_7000.txt
         post_alloc_hook+0x177/0x1a0
         get_page_from_freelist+0xd01/0xd80
         __alloc_pages+0x39e/0x7e0
         alloc_pages_mpol+0x22e/0x490
         folio_alloc+0xd5/0x110
         filemap_alloc_folio+0x78/0x230
         page_cache_ra_order+0x287/0x6f0
         filemap_get_pages+0x517/0x1160
         filemap_read+0x304/0x9f0
         xfs_file_buffered_read+0xe6/0x1d0 [xfs]
         xfs_file_read_iter+0x1f0/0x380 [xfs]
         __kernel_read+0x3b9/0x730
         kernel_read_file+0x309/0x4d0
         __do_sys_finit_module+0x381/0x730
         do_syscall_64+0x8d/0x150
         entry_SYSCALL_64_after_hwframe+0x62/0x6a
        nr_base_pages: 20824
        ...

        cat /sys/kernel/debug/page_owner > page_owner_full.txt
        ./page_owner_sort page_owner_full.txt sorted_page_owner.txt

전체 dump 형식과 기본 정렬

121-150

`page_owner_full.txt`의 일반 형식은 allocation order, PFN, 상세 stack이 한 block을 이루고 이 block이 반복되는 구조입니다. 기본 동작은 모든 PFN을 dump합니다.

지정 PFN부터 시작하려면 page owner가 지원하는 `fseek`를 사용할 수 있습니다.

FILE *fp = fopen("/sys/kernel/debug/page_owner", "r");
fseek(fp, pfn_start, SEEK_SET);

`page_owner_sort`는 `PFN` 행을 무시하고 나머지 행을 buffer에 넣습니다. Regular expression으로 page-order 값을 추출하고 동일 buffer가 나온 횟수와 page 수를 센 뒤 지정 parameter에 따라 정렬합니다.

`sorted_page_owner.txt`의 일반 출력은 `XXX times, XXX pages:` 뒤에 allocation order와 상세 stack이 이어집니다. 기본 정렬 기준은 같은 buffer의 출현 횟수이며, 전체 page 수로 정렬하려면 `-m`을 사용합니다.


   The general output of ``page_owner_full.txt`` is as follows::

        Page allocated via order XXX, ...
        PFN XXX ...
        // Detailed stack

        Page allocated via order XXX, ...
        PFN XXX ...
        // Detailed stack
    By default, it will do full pfn dump, to start with a given pfn,
    page_owner supports fseek.

    FILE *fp = fopen("/sys/kernel/debug/page_owner", "r");
    fseek(fp, pfn_start, SEEK_SET);

   The ``page_owner_sort`` tool ignores ``PFN`` rows, puts the remaining rows
   in buf, uses regexp to extract the page order value, counts the times
   and pages of buf, and finally sorts them according to the parameter(s).

   See the result about who allocated each page
   in the ``sorted_page_owner.txt``. General output::

        XXX times, XXX pages:
        Page allocated via order XXX, ...
        // Detailed stack

   By default, ``page_owner_sort`` is sorted according to the times of buf.
   If you want to sort by the page nums of buf, use the ``-m`` parameter.
   The detailed parameters are:

정렬·병합·필터·선택 option

151-210

기본 정렬 기능은 다음과 같습니다.

  • `-a`: memory allocation time으로 정렬합니다.
  • `-m`: total memory로 정렬합니다.
  • `-p`: PID로 정렬합니다.
  • `-P`: TGID로 정렬합니다.
  • `-n`: task command name으로 정렬합니다.
  • `-r`: memory release time으로 정렬합니다.
  • `-s`: stack trace로 정렬합니다.
  • `-t`: 횟수로 정렬하며 기본값입니다.
  • `--sort <order>`: 정렬 순서를 지정합니다. 문법은 `[+|-]key[,[+|-]key[,...]]`입니다. `+`는 숫자 또는 사전식 오름차순인 기본 방향이므로 생략할 수 있고, 축약 key와 전체 key를 섞어 쓸 수 있습니다.
./page_owner_sort <input> <output> --sort=n,+pid,-tgid
./page_owner_sort <input> <output> --sort=at

`--cull <rules>`는 block을 합칠 기준을 지정합니다. 문법은 `key[,key[,...]]`인 comma-separated 단일 argument이며, 아래 STANDARD FORMAT SPECIFIERS의 multi-letter key를 사용합니다. 축약 key와 전체 key를 섞을 수 있습니다.

./page_owner_sort <input> <output> --cull=stacktrace
./page_owner_sort <input> <output> --cull=st,pid,name
./page_owner_sort <input> <output> --cull=n,f

`-f`는 memory가 이미 release된 block 정보를 제외합니다.

`--pid <pidlist>`, `--tgid <tgidlist>`, `--name <cmdlist>`는 각각 process ID, thread-group ID, task command name이 comma-separated list에 있는 block만 선택합니다. 각 list는 개별 선택 규칙을 나열하는 하나의 argument입니다.

./page_owner_sort <input> <output> --pid=1
./page_owner_sort <input> <output> --tgid=1,2,3
./page_owner_sort <input> <output> --name name1,name2

   fundamental function::

        Sort:
                -a                Sort by memory allocation time.
                -m                Sort by total memory.
                -p                Sort by pid.
                -P                Sort by tgid.
                -n                Sort by task command name.
                -r                Sort by memory release time.
                -s                Sort by stack trace.
                -t                Sort by times (default).
                --sort <order>        Specify sorting order.  Sorting syntax is [+|-]key[,[+|-]key[,...]].
                                Choose a key from the **STANDARD FORMAT SPECIFIERS** section. The "+" is
                                optional since default direction is increasing numerical or lexicographic
                                order. Mixed use of abbreviated and complete-form of keys is allowed.

                Examples:
                                ./page_owner_sort <input> <output> --sort=n,+pid,-tgid
                                ./page_owner_sort <input> <output> --sort=at

   additional function::

        Cull:
                --cull <rules>
                                Specify culling rules.Culling syntax is key[,key[,...]].Choose a
                                multi-letter key from the **STANDARD FORMAT SPECIFIERS** section.

                <rules> is a single argument in the form of a comma-separated list,
                which offers a way to specify individual culling rules.  The recognized
                keywords are described in the **STANDARD FORMAT SPECIFIERS** section below.
                <rules> can be specified by the sequence of keys k1,k2, ..., as described in
                the STANDARD SORT KEYS section below. Mixed use of abbreviated and
                complete-form of keys is allowed.

                Examples:
                                ./page_owner_sort <input> <output> --cull=stacktrace
                                ./page_owner_sort <input> <output> --cull=st,pid,name
                                ./page_owner_sort <input> <output> --cull=n,f

        Filter:
                -f                Filter out the information of blocks whose memory has been released.

        Select:
                --pid <pidlist>                Select by pid. This selects the blocks whose process ID
                                        numbers appear in <pidlist>.
                --tgid <tgidlist>        Select by tgid. This selects the blocks whose thread
                                        group ID numbers appear in <tgidlist>.
                --name <cmdlist>        Select by task command name. This selects the blocks whose
                                        task command name appear in <cmdlist>.

                <pidlist>, <tgidlist>, <cmdlist> are single arguments in the form of a comma-separated list,
                which offers a way to specify individual selecting rules.


                Examples:
                                ./page_owner_sort <input> <output> --pid=1
                                ./page_owner_sort <input> <output> --tgid=1,2,3
                                ./page_owner_sort <input> <output> --name name1,name2

STANDARD FORMAT SPECIFIERS

211-235

`--sort` option에서 사용할 수 있는 key는 다음과 같습니다.

  • `p` / `pid`: process ID
  • `tg` / `tgid`: thread-group ID
  • `n` / `name`: task command name
  • `st` / `stacktrace`: page-allocation stack trace
  • `T` / `txt`: block의 full text
  • `ft` / `free_ts`: page가 release된 timestamp
  • `at` / `alloc_ts`: page가 allocated된 timestamp
  • `ator` / `allocator`: page용 memory allocator

`--cull` option에서 사용할 수 있는 key는 다음과 같습니다.

  • `p` / `pid`: process ID
  • `tg` / `tgid`: thread-group ID
  • `n` / `name`: task command name
  • `f` / `free`: page release 여부
  • `st` / `stacktrace`: page-allocation stack trace
  • `ator` / `allocator`: page용 memory allocator
STANDARD FORMAT SPECIFIERS
==========================
::

  For --sort option:

        KEY                LONG                DESCRIPTION
        p                pid                process ID
        tg                tgid                thread group ID
        n                name                task command name
        st                stacktrace        stack trace of the page allocation
        T                txt                full text of block
        ft                free_ts                timestamp of the page when it was released
        at                alloc_ts        timestamp of the page when it was allocated
        ator                allocator        memory allocator for pages

  For --cull option:

        KEY                LONG                DESCRIPTION
        p                pid                process ID
        tg                tgid                thread group ID
        n                name                task command name
        f                free                whether the page has been released or not
        st                stacktrace        stack trace of the page allocation
        ator                allocator        memory allocator for pages