요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
==================================================
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.
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.
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
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:
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
==========================
::
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
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Page owner의 목적
1-30Page 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-61Page 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
요약·해설
page_owner.rst:1-235Page owner는 page별 allocation stack, order와 allocator 정보를 보존해 memory leak과 큰 allocation source를 찾습니다. Stack별 base-page 수를 빠르게 보거나 전체 PFN dump를 `page_owner_sort`로 정렬·병합·필터할 수 있습니다.
Boot-time 수집부터 stack 요약 또는 전체 dump 분석까지의 경로입니다.
정렬, cull, filter와 select가 서로 다른 분석 단계를 담당합니다.