요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
========
zsmalloc
========
This allocator is designed for use with zram. Thus, the allocator is
supposed to work well under low memory conditions. In particular, it
never attempts higher order page allocation which is very likely to
fail under memory pressure. On the other hand, if we just use single
(0-order) pages, it would suffer from very high fragmentation --
any object of size PAGE_SIZE/2 or larger would occupy an entire page.
This was one of the major issues with its predecessor (xvmalloc).
To overcome these issues, zsmalloc allocates a bunch of 0-order pages
and links them together using various 'struct page' fields. These linked
pages act as a single higher-order page i.e. an object can span 0-order
page boundaries. The code refers to these linked pages as a single entity
called zspage.
For simplicity, zsmalloc can only allocate objects of size up to PAGE_SIZE
since this satisfies the requirements of all its current users (in the
worst case, page is incompressible and is thus stored "as-is" i.e. in
uncompressed form). For allocation requests larger than this size, failure
is returned (see zs_malloc).
Additionally, zs_malloc() does not return a dereferenceable pointer.
Instead, it returns an opaque handle (unsigned long) which encodes actual
location of the allocated object. The reason for this indirection is that
zsmalloc does not keep zspages permanently mapped since that would cause
issues on 32-bit systems where the VA region for kernel space mappings
is very small. So, using the allocated memory should be done through the
proper handle-based APIs.
stat
====
With CONFIG_ZSMALLOC_STAT, we could see zsmalloc internal information via
``/sys/kernel/debug/zsmalloc/<user name>``. Here is a sample of stat output::
# cat /sys/kernel/debug/zsmalloc/zram0/classes
class size 10% 20% 30% 40% 50% 60% 70% 80% 90% 99% 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
...
30 512 0 12 4 1 0 1 0 0 1 0 414 3464 3346 433 1 14
31 528 2 7 2 2 1 0 1 0 0 2 117 4154 3793 536 4 44
32 544 6 3 4 1 2 1 0 0 0 1 260 4170 3965 556 2 26
...
...
class
index
size
object size zspage stores
10%
the number of zspages with usage ratio less than 10% (see below)
20%
the number of zspages with usage ratio between 10% and 20%
30%
the number of zspages with usage ratio between 20% and 30%
40%
the number of zspages with usage ratio between 30% and 40%
50%
the number of zspages with usage ratio between 40% and 50%
60%
the number of zspages with usage ratio between 50% and 60%
70%
the number of zspages with usage ratio between 60% and 70%
80%
the number of zspages with usage ratio between 70% and 80%
90%
the number of zspages with usage ratio between 80% and 90%
99%
the number of zspages with usage ratio between 90% and 99%
100%
the number of zspages with usage ratio 100%
obj_allocated
the number of objects allocated
obj_used
the number of objects allocated to the user
pages_used
the number of pages allocated for the class
pages_per_zspage
the number of 0-order pages to make a zspage
freeable
the approximate number of pages class compaction can free
Each zspage maintains inuse counter which keeps track of the number of
objects stored in the zspage. The inuse counter determines the zspage's
"fullness group" which is calculated as the ratio of the "inuse" objects to
the total number of objects the zspage can hold (objs_per_zspage). The
closer the inuse counter is to objs_per_zspage, the better.
Internals
=========
zsmalloc has 255 size classes, each of which can hold a number of zspages.
Each zspage can contain up to ZSMALLOC_CHAIN_SIZE physical (0-order) pages.
The optimal zspage chain size for each size class is calculated during the
creation of the zsmalloc pool (see calculate_zspage_chain_size()).
As an optimization, zsmalloc merges size classes that have similar
characteristics in terms of the number of pages per zspage and the number
of objects that each zspage can store.
For instance, consider the following size classes:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
94 1536 0 .... 0 0 0 0 3 0
100 1632 0 .... 0 0 0 0 2 0
...
Size classes #95-99 are merged with size class #100. This means that when we
need to store an object of size, say, 1568 bytes, we end up using size class
#100 instead of size class #96. Size class #100 is meant for objects of size
1632 bytes, so each object of size 1568 bytes wastes 1632-1568=64 bytes.
Size class #100 consists of zspages with 2 physical pages each, which can
hold a total of 5 objects. If we need to store 13 objects of size 1568, we
end up allocating three zspages, or 6 physical pages.
However, if we take a closer look at size class #96 (which is meant for
objects of size 1568 bytes) and trace `calculate_zspage_chain_size()`, we
find that the most optimal zspage configuration for this class is a chain
of 5 physical pages:::
pages per zspage wasted bytes used%
1 960 76
2 352 95
3 1312 89
4 704 95
5 96 99
This means that a class #96 configuration with 5 physical pages can store 13
objects of size 1568 in a single zspage, using a total of 5 physical pages.
This is more efficient than the class #100 configuration, which would use 6
physical pages to store the same number of objects.
As the zspage chain size for class #96 increases, its key characteristics
such as pages per-zspage and objects per-zspage also change. This leads to
dewer class mergers, resulting in a more compact grouping of classes, which
reduces memory wastage.
Let's take a closer look at the bottom of `/sys/kernel/debug/zsmalloc/zramX/classes`:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
202 3264 0 .. 0 0 0 0 4 0
254 4096 0 .. 0 0 0 0 1 0
...
Size class #202 stores objects of size 3264 bytes and has a maximum of 4 pages
per zspage. Any object larger than 3264 bytes is considered huge and belongs
to size class #254, which stores each object in its own physical page (objects
in huge classes do not share pages).
Increasing the size of the chain of zspages also results in a higher watermark
for the huge size class and fewer huge classes overall. This allows for more
efficient storage of large objects.
For zspage chain size of 8, huge class watermark becomes 3632 bytes:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
202 3264 0 .. 0 0 0 0 4 0
211 3408 0 .. 0 0 0 0 5 0
217 3504 0 .. 0 0 0 0 6 0
222 3584 0 .. 0 0 0 0 7 0
225 3632 0 .. 0 0 0 0 8 0
254 4096 0 .. 0 0 0 0 1 0
...
For zspage chain size of 16, huge class watermark becomes 3840 bytes:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
202 3264 0 .. 0 0 0 0 4 0
206 3328 0 .. 0 0 0 0 13 0
207 3344 0 .. 0 0 0 0 9 0
208 3360 0 .. 0 0 0 0 14 0
211 3408 0 .. 0 0 0 0 5 0
212 3424 0 .. 0 0 0 0 16 0
214 3456 0 .. 0 0 0 0 11 0
217 3504 0 .. 0 0 0 0 6 0
219 3536 0 .. 0 0 0 0 13 0
222 3584 0 .. 0 0 0 0 7 0
223 3600 0 .. 0 0 0 0 15 0
225 3632 0 .. 0 0 0 0 8 0
228 3680 0 .. 0 0 0 0 9 0
230 3712 0 .. 0 0 0 0 10 0
232 3744 0 .. 0 0 0 0 11 0
234 3776 0 .. 0 0 0 0 12 0
235 3792 0 .. 0 0 0 0 13 0
236 3808 0 .. 0 0 0 0 14 0
238 3840 0 .. 0 0 0 0 15 0
254 4096 0 .. 0 0 0 0 1 0
...
Overall the combined zspage chain size effect on zsmalloc pool configuration:::
pages per zspage number of size classes (clusters) huge size class watermark
4 69 3264
5 86 3408
6 93 3504
7 112 3584
8 123 3632
9 140 3680
10 143 3712
11 159 3744
12 164 3776
13 180 3792
14 183 3808
15 188 3840
16 191 3840
A synthetic test
----------------
zram as a build artifacts storage (Linux kernel compilation).
* `CONFIG_ZSMALLOC_CHAIN_SIZE=4`
zsmalloc classes stats:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
Total 13 .. 51 413836 412973 159955 3
zram mm_stat:::
1691783168 628083717 655175680 0 655175680 60 0 34048 34049
* `CONFIG_ZSMALLOC_CHAIN_SIZE=8`
zsmalloc classes stats:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
Total 18 .. 87 414852 412978 156666 0
zram mm_stat:::
1691803648 627793930 641703936 0 641703936 60 0 33591 33591
Using larger zspage chains may result in using fewer physical pages, as seen
in the example where the number of physical pages used decreased from 159955
to 156666, at the same time maximum zsmalloc pool memory usage went down from
655175680 to 641703936 bytes.
However, this advantage may be offset by the potential for increased system
memory pressure (as some zspages have larger chain sizes) in cases where there
is heavy internal fragmentation and zspool compaction is unable to relocate
objects and release zspages. In these cases, it is recommended to decrease
the limit on the size of the zspage chains (as specified by the
CONFIG_ZSMALLOC_CHAIN_SIZE option).
Functions
=========
.. kernel-doc:: mm/zsmalloc.c
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
0-order page를 연결한 zspage
1-32zsmalloc
이 allocator는 zram용으로 설계되어 low-memory 상황에서도 잘 동작해야 합니다. Memory pressure에서 실패하기 쉬운 higher-order page allocation을 전혀 시도하지 않습니다.
반대로 0-order page만 독립적으로 사용하면 fragmentation이 매우 커집니다. `PAGE_SIZE/2` 이상인 object가 page 전체를 차지하는 문제가 전신인 xvmalloc의 주요 약점이었습니다.
zsmalloc은 여러 0-order page를 할당하고 다양한 `struct page` field로 연결합니다. 연결된 page는 하나의 higher-order page처럼 동작해 object가 0-order page 경계를 넘을 수 있습니다. 이 묶음을 `zspage`라고 합니다.
현재 사용자의 요구를 충족하므로 zsmalloc은 단순화를 위해 최대 `PAGE_SIZE` 크기의 object만 할당합니다. 압축할 수 없는 page도 최악의 경우 원형 그대로 저장할 수 있습니다. 더 큰 요청에는 `zs_malloc`이 실패를 반환합니다.
`zs_malloc()`은 dereference 가능한 pointer 대신 실제 object 위치를 encode한 opaque `unsigned long` handle을 반환합니다. 32비트 시스템은 kernel mapping용 virtual-address 영역이 작으므로 zspage를 영구 mapping하지 않습니다. 할당 memory는 반드시 handle 기반 API로 접근해야 합니다.
========
zsmalloc
========
This allocator is designed for use with zram. Thus, the allocator is
supposed to work well under low memory conditions. In particular, it
never attempts higher order page allocation which is very likely to
fail under memory pressure. On the other hand, if we just use single
(0-order) pages, it would suffer from very high fragmentation --
any object of size PAGE_SIZE/2 or larger would occupy an entire page.
This was one of the major issues with its predecessor (xvmalloc).
To overcome these issues, zsmalloc allocates a bunch of 0-order pages
and links them together using various 'struct page' fields. These linked
pages act as a single higher-order page i.e. an object can span 0-order
page boundaries. The code refers to these linked pages as a single entity
called zspage.
For simplicity, zsmalloc can only allocate objects of size up to PAGE_SIZE
since this satisfies the requirements of all its current users (in the
worst case, page is incompressible and is thus stored "as-is" i.e. in
uncompressed form). For allocation requests larger than this size, failure
is returned (see zs_malloc).
Additionally, zs_malloc() does not return a dereferenceable pointer.
Instead, it returns an opaque handle (unsigned long) which encodes actual
location of the allocated object. The reason for this indirection is that
zsmalloc does not keep zspages permanently mapped since that would cause
issues on 32-bit systems where the VA region for kernel space mappings
is very small. So, using the allocated memory should be done through the
proper handle-based APIs.
Debugfs 통계와 fullness group
33-93통계
`CONFIG_ZSMALLOC_STAT`을 활성화하면 `/sys/kernel/debug/zsmalloc/<user name>`에서 내부 정보를 볼 수 있습니다. 원문은 `zram0/classes` 출력 예를 제공합니다.
- `class`: size-class index입니다.
- `size`: 해당 zspage가 저장하는 object size입니다.
- `10%`부터 `99%`: 직전 구간보다 크거나 같고 해당 비율보다 작은 usage ratio의 zspage 수입니다. `10%`는 10% 미만입니다.
- `100%`: usage ratio가 100%인 zspage 수입니다.
- `obj_allocated`: 할당된 object slot 수입니다.
- `obj_used`: 사용자에게 실제 할당된 object 수입니다.
- `pages_used`: class가 할당한 physical page 수입니다.
- `pages_per_zspage`: zspage 하나를 만드는 0-order page 수입니다.
- `freeable`: class compaction으로 free할 수 있는 대략적인 page 수입니다.
각 zspage의 `inuse` counter는 저장된 object 수를 추적합니다. `inuse / objs_per_zspage` 비율이 fullness group을 정하며, `inuse`가 `objs_per_zspage`에 가까울수록 공간 활용이 좋습니다.
stat
====
With CONFIG_ZSMALLOC_STAT, we could see zsmalloc internal information via
``/sys/kernel/debug/zsmalloc/<user name>``. Here is a sample of stat output::
# cat /sys/kernel/debug/zsmalloc/zram0/classes
class size 10% 20% 30% 40% 50% 60% 70% 80% 90% 99% 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
...
30 512 0 12 4 1 0 1 0 0 1 0 414 3464 3346 433 1 14
31 528 2 7 2 2 1 0 1 0 0 2 117 4154 3793 536 4 44
32 544 6 3 4 1 2 1 0 0 0 1 260 4170 3965 556 2 26
...
...
class
index
size
object size zspage stores
10%
the number of zspages with usage ratio less than 10% (see below)
20%
the number of zspages with usage ratio between 10% and 20%
30%
the number of zspages with usage ratio between 20% and 30%
40%
the number of zspages with usage ratio between 30% and 40%
50%
the number of zspages with usage ratio between 40% and 50%
60%
the number of zspages with usage ratio between 50% and 60%
70%
the number of zspages with usage ratio between 60% and 70%
80%
the number of zspages with usage ratio between 70% and 80%
90%
the number of zspages with usage ratio between 80% and 90%
99%
the number of zspages with usage ratio between 90% and 99%
100%
the number of zspages with usage ratio 100%
obj_allocated
the number of objects allocated
obj_used
the number of objects allocated to the user
pages_used
the number of pages allocated for the class
pages_per_zspage
the number of 0-order pages to make a zspage
freeable
the approximate number of pages class compaction can free
Each zspage maintains inuse counter which keeps track of the number of
objects stored in the zspage. The inuse counter determines the zspage's
"fullness group" which is calculated as the ratio of the "inuse" objects to
the total number of objects the zspage can hold (objs_per_zspage). The
closer the inuse counter is to objs_per_zspage, the better.
Size class 병합의 비용과 이득
94-145내부 구조
zsmalloc에는 255개 size class가 있고 각 class는 여러 zspage를 가질 수 있습니다. Zspage 하나는 최대 `ZSMALLOC_CHAIN_SIZE`개의 physical 0-order page를 연결합니다. Pool 생성 시 `calculate_zspage_chain_size()`가 class별 최적 chain size를 계산합니다.
Zspage당 page 수와 저장 가능한 object 수가 비슷한 size class는 최적화로 병합합니다.
예를 들어 class 95~99를 class 100에 병합하면 1,568-byte object도 원래 class 96 대신 1,632-byte용 class 100을 사용합니다. Object마다 `1632 - 1568 = 64` byte가 낭비됩니다.
Class 100의 zspage는 physical page 2개로 object 5개를 담습니다. 1,568-byte object 13개를 저장하려면 zspage 3개, 즉 physical page 6개가 필요합니다.
반면 class 96의 최적 구성은 physical page 5개를 연결한 zspage 하나입니다. Page 수 1~5일 때 낭비는 각각 960·352·1,312·704·96 byte이며 사용률은 76·95·89·95·99%입니다.
따라서 class 96은 5 page로 13개를 한 zspage에 담아 class 100의 6 page보다 효율적입니다. Chain size가 늘면 pages-per-zspage와 objects-per-zspage도 달라져 class 병합이 줄고 더 촘촘한 grouping으로 memory 낭비가 감소합니다.
Internals
=========
zsmalloc has 255 size classes, each of which can hold a number of zspages.
Each zspage can contain up to ZSMALLOC_CHAIN_SIZE physical (0-order) pages.
The optimal zspage chain size for each size class is calculated during the
creation of the zsmalloc pool (see calculate_zspage_chain_size()).
As an optimization, zsmalloc merges size classes that have similar
characteristics in terms of the number of pages per zspage and the number
of objects that each zspage can store.
For instance, consider the following size classes:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
94 1536 0 .... 0 0 0 0 3 0
100 1632 0 .... 0 0 0 0 2 0
...
Size classes #95-99 are merged with size class #100. This means that when we
need to store an object of size, say, 1568 bytes, we end up using size class
#100 instead of size class #96. Size class #100 is meant for objects of size
1632 bytes, so each object of size 1568 bytes wastes 1632-1568=64 bytes.
Size class #100 consists of zspages with 2 physical pages each, which can
hold a total of 5 objects. If we need to store 13 objects of size 1568, we
end up allocating three zspages, or 6 physical pages.
However, if we take a closer look at size class #96 (which is meant for
objects of size 1568 bytes) and trace `calculate_zspage_chain_size()`, we
find that the most optimal zspage configuration for this class is a chain
of 5 physical pages:::
pages per zspage wasted bytes used%
1 960 76
2 352 95
3 1312 89
4 704 95
5 96 99
This means that a class #96 configuration with 5 physical pages can store 13
objects of size 1568 in a single zspage, using a total of 5 physical pages.
This is more efficient than the class #100 configuration, which would use 6
physical pages to store the same number of objects.
As the zspage chain size for class #96 increases, its key characteristics
such as pages per-zspage and objects per-zspage also change. This leads to
dewer class mergers, resulting in a more compact grouping of classes, which
reduces memory wastage.
Huge class watermark와 chain size
146-176`/sys/kernel/debug/zsmalloc/zramX/classes`의 하단 예에서 class 202는 3,264-byte object를 저장하고 zspage당 최대 4 page를 사용합니다. 3,264 byte보다 큰 object는 huge로 간주되어 class 254에 들어가며, 각 object가 physical page 하나를 독점합니다.
Zspage chain 상한을 늘리면 huge class가 시작되는 watermark가 높아지고 huge class 수가 줄어 large object를 더 효율적으로 저장할 수 있습니다.
Chain size 8에서는 일반 class가 3,632 byte까지 이어진 뒤 4,096-byte class 254로 넘어갑니다. 중간 class는 3,408·3,504·3,584·3,632 byte이며 zspage당 각각 5·6·7·8 page를 사용합니다.
Let's take a closer look at the bottom of `/sys/kernel/debug/zsmalloc/zramX/classes`:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
202 3264 0 .. 0 0 0 0 4 0
254 4096 0 .. 0 0 0 0 1 0
...
Size class #202 stores objects of size 3264 bytes and has a maximum of 4 pages
per zspage. Any object larger than 3264 bytes is considered huge and belongs
to size class #254, which stores each object in its own physical page (objects
in huge classes do not share pages).
Increasing the size of the chain of zspages also results in a higher watermark
for the huge size class and fewer huge classes overall. This allows for more
efficient storage of large objects.
For zspage chain size of 8, huge class watermark becomes 3632 bytes:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
202 3264 0 .. 0 0 0 0 4 0
211 3408 0 .. 0 0 0 0 5 0
217 3504 0 .. 0 0 0 0 6 0
222 3584 0 .. 0 0 0 0 7 0
225 3632 0 .. 0 0 0 0 8 0
254 4096 0 .. 0 0 0 0 1 0
...
Chain size 16과 pool 구성 변화
177-220Chain size 16에서는 huge class watermark가 3,840 byte로 올라갑니다. 3,264~3,840 byte 사이에 9~16 page를 쓰는 더 많은 size class가 유지되고, 4,096-byte object만 class 254에서 page 하나를 독점합니다.
전체 효과를 보면 pages-per-zspage 상한이 4에서 16으로 증가할 때 size class cluster 수는 69에서 191로 늘고 huge watermark는 3,264에서 3,840 byte로 올라갑니다.
원문 표의 단계별 값은 4→69/3264, 5→86/3408, 6→93/3504, 7→112/3584, 8→123/3632, 9→140/3680, 10→143/3712, 11→159/3744, 12→164/3776, 13→180/3792, 14→183/3808, 15→188/3840, 16→191/3840입니다. 각 쌍은 size-class 수와 huge watermark를 뜻합니다.
For zspage chain size of 16, huge class watermark becomes 3840 bytes:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
202 3264 0 .. 0 0 0 0 4 0
206 3328 0 .. 0 0 0 0 13 0
207 3344 0 .. 0 0 0 0 9 0
208 3360 0 .. 0 0 0 0 14 0
211 3408 0 .. 0 0 0 0 5 0
212 3424 0 .. 0 0 0 0 16 0
214 3456 0 .. 0 0 0 0 11 0
217 3504 0 .. 0 0 0 0 6 0
219 3536 0 .. 0 0 0 0 13 0
222 3584 0 .. 0 0 0 0 7 0
223 3600 0 .. 0 0 0 0 15 0
225 3632 0 .. 0 0 0 0 8 0
228 3680 0 .. 0 0 0 0 9 0
230 3712 0 .. 0 0 0 0 10 0
232 3744 0 .. 0 0 0 0 11 0
234 3776 0 .. 0 0 0 0 12 0
235 3792 0 .. 0 0 0 0 13 0
236 3808 0 .. 0 0 0 0 14 0
238 3840 0 .. 0 0 0 0 15 0
254 4096 0 .. 0 0 0 0 1 0
...
Overall the combined zspage chain size effect on zsmalloc pool configuration:::
pages per zspage number of size classes (clusters) huge size class watermark
4 69 3264
5 86 3408
6 93 3504
7 112 3584
8 123 3632
9 140 3680
10 143 3712
11 159 3744
12 164 3776
13 180 3792
14 183 3808
15 188 3840
16 191 3840
Kernel build artifact 합성 시험
221-265합성 시험
Linux kernel build artifact를 zram에 저장한 시험에서 `CONFIG_ZSMALLOC_CHAIN_SIZE=4` 구성은 object 413,836개를 할당해 412,973개를 사용했고 physical page 159,955개, 최대 pool memory 655,175,680 byte를 사용했습니다.
`CONFIG_ZSMALLOC_CHAIN_SIZE=8`에서는 object 414,852개를 할당해 412,978개를 사용했고 physical page 156,666개, 최대 pool memory 641,703,936 byte를 사용했습니다.
더 큰 chain은 이 예처럼 physical page 수를 159,955에서 156,666으로, 최대 pool memory를 655,175,680에서 641,703,936 byte로 줄일 수 있습니다.
하지만 internal fragmentation이 심하고 zspool compaction이 object를 옮겨 zspage를 해제하지 못하면 큰 chain의 zspage 때문에 system memory pressure가 오히려 커질 수 있습니다. 이런 경우 `CONFIG_ZSMALLOC_CHAIN_SIZE`로 chain-size 상한을 낮추는 것이 권장됩니다.
A synthetic test
----------------
zram as a build artifacts storage (Linux kernel compilation).
* `CONFIG_ZSMALLOC_CHAIN_SIZE=4`
zsmalloc classes stats:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
Total 13 .. 51 413836 412973 159955 3
zram mm_stat:::
1691783168 628083717 655175680 0 655175680 60 0 34048 34049
* `CONFIG_ZSMALLOC_CHAIN_SIZE=8`
zsmalloc classes stats:::
class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
...
Total 18 .. 87 414852 412978 156666 0
zram mm_stat:::
1691803648 627793930 641703936 0 641703936 60 0 33591 33591
Using larger zspage chains may result in using fewer physical pages, as seen
in the example where the number of physical pages used decreased from 159955
to 156666, at the same time maximum zsmalloc pool memory usage went down from
655175680 to 641703936 bytes.
However, this advantage may be offset by the potential for increased system
memory pressure (as some zspages have larger chain sizes) in cases where there
is heavy internal fragmentation and zspool compaction is unable to relocate
objects and release zspages. In these cases, it is recommended to decrease
the limit on the size of the zspage chains (as specified by the
CONFIG_ZSMALLOC_CHAIN_SIZE option).
함수 문서
266-269함수
이 절은 `mm/zsmalloc.c`의 kernel-doc 주석에서 함수 문서를 생성해 포함합니다.
Functions
=========
.. kernel-doc:: mm/zsmalloc.c
요약·해설
zsmalloc.rst:1-269zsmalloc은 memory pressure에서 higher-order allocation을 피하면서도 여러 0-order page를 zspage로 연결해 object가 page 경계를 넘게 합니다. Size class와 chain size를 조절하면 internal fragmentation과 huge-object 전용 page를 줄일 수 있지만, compaction이 실패하는 workload에서는 큰 chain 자체가 pressure를 높일 수 있습니다.
물리 page는 order-0으로 할당하고 논리적 chain에서 object를 연속 배치합니다.
Debugfs classes 출력의 핵심 field를 요약합니다.
Inuse 비율이 높을수록 zspage 내부 공간을 잘 사용합니다.
Class 병합이 object당 낭비와 총 page 수에 미치는 영향을 보여줍니다.
원문 전체 집계 표에서 대표 지점을 뽑았습니다.
Chain 상한 4와 8의 실측 결과를 비교합니다.