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

Linux 6.18.37 · Memory management

zsmalloc

0-order page chain, handle API, size class 병합과 chain-size trade-off를 설명합니다.

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

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

1. 요약·해설

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

요약·해설

zsmalloc.rst:1-269

zsmalloc은 memory pressure에서 higher-order allocation을 피하면서도 여러 0-order page를 zspage로 연결해 object가 page 경계를 넘게 합니다. Size class와 chain size를 조절하면 internal fragmentation과 huge-object 전용 page를 줄일 수 있지만, compaction이 실패하는 workload에서는 큰 chain 자체가 pressure를 높일 수 있습니다.

0-order page에서 zspage로
0-order page AZspage chainObject 앞부분
0-order page BZspage chainObject 뒷부분
`zs_malloc()`Opaque handleMap API일시 virtual mappingObject 접근

물리 page는 order-0으로 할당하고 논리적 chain에서 object를 연속 배치합니다.

주요 zsmalloc 통계
Field의미
`class`Size-class index
`size`저장 object size
`10%`~`100%`Fullness group별 zspage 수
`obj_allocated`할당된 slot 수
`obj_used`사용자에게 배정된 object 수
`pages_used`Class의 physical page 수
`pages_per_zspage`Zspage당 0-order page 수
`freeable`Compaction으로 해제 가능한 근사 page 수

Debugfs classes 출력의 핵심 field를 요약합니다.

Fullness group 계산
`inuse` objects`objs_per_zspage`로 나눔Usage ratio10%~100% fullness group

Inuse 비율이 높을수록 zspage 내부 공간을 잘 사용합니다.

1,568-byte object 13개의 배치 비교
구성Zspage당 pagesZspage 수총 pages낭비
Class 100, slot 1,632B236Object당 64B
Class 96, slot 1,568B515Zspage당 96B

Class 병합이 object당 낭비와 총 page 수에 미치는 영향을 보여줍니다.

Chain 상한과 pool 구성
Pages per zspageSize-class 수Huge watermark
4693,264B
81233,632B
121643,776B
151883,840B
161913,840B

원문 전체 집계 표에서 대표 지점을 뽑았습니다.

Kernel-build 합성 시험
구성사용 objectsPhysical pages최대 pool memory
`CHAIN_SIZE=4`412,973159,955655,175,680B
`CHAIN_SIZE=8`412,978156,666641,703,936B

Chain 상한 4와 8의 실측 결과를 비교합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 ========
2 zsmalloc
3 ========
4
5 This allocator is designed for use with zram. Thus, the allocator is
6 supposed to work well under low memory conditions. In particular, it
7 never attempts higher order page allocation which is very likely to
8 fail under memory pressure. On the other hand, if we just use single
9 (0-order) pages, it would suffer from very high fragmentation --
10 any object of size PAGE_SIZE/2 or larger would occupy an entire page.
11 This was one of the major issues with its predecessor (xvmalloc).
12
13 To overcome these issues, zsmalloc allocates a bunch of 0-order pages
14 and links them together using various 'struct page' fields. These linked
15 pages act as a single higher-order page i.e. an object can span 0-order
16 page boundaries. The code refers to these linked pages as a single entity
17 called zspage.
18
19 For simplicity, zsmalloc can only allocate objects of size up to PAGE_SIZE
20 since this satisfies the requirements of all its current users (in the
21 worst case, page is incompressible and is thus stored "as-is" i.e. in
22 uncompressed form). For allocation requests larger than this size, failure
23 is returned (see zs_malloc).
24
25 Additionally, zs_malloc() does not return a dereferenceable pointer.
26 Instead, it returns an opaque handle (unsigned long) which encodes actual
27 location of the allocated object. The reason for this indirection is that
28 zsmalloc does not keep zspages permanently mapped since that would cause
29 issues on 32-bit systems where the VA region for kernel space mappings
30 is very small. So, using the allocated memory should be done through the
31 proper handle-based APIs.
32
33 stat
34 ====
35
36 With CONFIG_ZSMALLOC_STAT, we could see zsmalloc internal information via
37 ``/sys/kernel/debug/zsmalloc/<user name>``. Here is a sample of stat output::
38
39 # cat /sys/kernel/debug/zsmalloc/zram0/classes
40
41 class size 10% 20% 30% 40% 50% 60% 70% 80% 90% 99% 100% obj_allocated obj_used pages_used pages_per_zspage freeable
42 ...
43 ...
44 30 512 0 12 4 1 0 1 0 0 1 0 414 3464 3346 433 1 14
45 31 528 2 7 2 2 1 0 1 0 0 2 117 4154 3793 536 4 44
46 32 544 6 3 4 1 2 1 0 0 0 1 260 4170 3965 556 2 26
47 ...
48 ...
49
50
51 class
52 index
53 size
54 object size zspage stores
55 10%
56 the number of zspages with usage ratio less than 10% (see below)
57 20%
58 the number of zspages with usage ratio between 10% and 20%
59 30%
60 the number of zspages with usage ratio between 20% and 30%
61 40%
62 the number of zspages with usage ratio between 30% and 40%
63 50%
64 the number of zspages with usage ratio between 40% and 50%
65 60%
66 the number of zspages with usage ratio between 50% and 60%
67 70%
68 the number of zspages with usage ratio between 60% and 70%
69 80%
70 the number of zspages with usage ratio between 70% and 80%
71 90%
72 the number of zspages with usage ratio between 80% and 90%
73 99%
74 the number of zspages with usage ratio between 90% and 99%
75 100%
76 the number of zspages with usage ratio 100%
77 obj_allocated
78 the number of objects allocated
79 obj_used
80 the number of objects allocated to the user
81 pages_used
82 the number of pages allocated for the class
83 pages_per_zspage
84 the number of 0-order pages to make a zspage
85 freeable
86 the approximate number of pages class compaction can free
87
88 Each zspage maintains inuse counter which keeps track of the number of
89 objects stored in the zspage. The inuse counter determines the zspage's
90 "fullness group" which is calculated as the ratio of the "inuse" objects to
91 the total number of objects the zspage can hold (objs_per_zspage). The
92 closer the inuse counter is to objs_per_zspage, the better.
93
94 Internals
95 =========
96
97 zsmalloc has 255 size classes, each of which can hold a number of zspages.
98 Each zspage can contain up to ZSMALLOC_CHAIN_SIZE physical (0-order) pages.
99 The optimal zspage chain size for each size class is calculated during the
100 creation of the zsmalloc pool (see calculate_zspage_chain_size()).
101
102 As an optimization, zsmalloc merges size classes that have similar
103 characteristics in terms of the number of pages per zspage and the number
104 of objects that each zspage can store.
105
106 For instance, consider the following size classes:::
107
108 class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
109 ...
110 94 1536 0 .... 0 0 0 0 3 0
111 100 1632 0 .... 0 0 0 0 2 0
112 ...
113
114
115 Size classes #95-99 are merged with size class #100. This means that when we
116 need to store an object of size, say, 1568 bytes, we end up using size class
117 #100 instead of size class #96. Size class #100 is meant for objects of size
118 1632 bytes, so each object of size 1568 bytes wastes 1632-1568=64 bytes.
119
120 Size class #100 consists of zspages with 2 physical pages each, which can
121 hold a total of 5 objects. If we need to store 13 objects of size 1568, we
122 end up allocating three zspages, or 6 physical pages.
123
124 However, if we take a closer look at size class #96 (which is meant for
125 objects of size 1568 bytes) and trace `calculate_zspage_chain_size()`, we
126 find that the most optimal zspage configuration for this class is a chain
127 of 5 physical pages:::
128
129 pages per zspage wasted bytes used%
130 1 960 76
131 2 352 95
132 3 1312 89
133 4 704 95
134 5 96 99
135
136 This means that a class #96 configuration with 5 physical pages can store 13
137 objects of size 1568 in a single zspage, using a total of 5 physical pages.
138 This is more efficient than the class #100 configuration, which would use 6
139 physical pages to store the same number of objects.
140
141 As the zspage chain size for class #96 increases, its key characteristics
142 such as pages per-zspage and objects per-zspage also change. This leads to
143 dewer class mergers, resulting in a more compact grouping of classes, which
144 reduces memory wastage.
145
146 Let's take a closer look at the bottom of `/sys/kernel/debug/zsmalloc/zramX/classes`:::
147
148 class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
149
150 ...
151 202 3264 0 .. 0 0 0 0 4 0
152 254 4096 0 .. 0 0 0 0 1 0
153 ...
154
155 Size class #202 stores objects of size 3264 bytes and has a maximum of 4 pages
156 per zspage. Any object larger than 3264 bytes is considered huge and belongs
157 to size class #254, which stores each object in its own physical page (objects
158 in huge classes do not share pages).
159
160 Increasing the size of the chain of zspages also results in a higher watermark
161 for the huge size class and fewer huge classes overall. This allows for more
162 efficient storage of large objects.
163
164 For zspage chain size of 8, huge class watermark becomes 3632 bytes:::
165
166 class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
167
168 ...
169 202 3264 0 .. 0 0 0 0 4 0
170 211 3408 0 .. 0 0 0 0 5 0
171 217 3504 0 .. 0 0 0 0 6 0
172 222 3584 0 .. 0 0 0 0 7 0
173 225 3632 0 .. 0 0 0 0 8 0
174 254 4096 0 .. 0 0 0 0 1 0
175 ...
176
177 For zspage chain size of 16, huge class watermark becomes 3840 bytes:::
178
179 class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
180
181 ...
182 202 3264 0 .. 0 0 0 0 4 0
183 206 3328 0 .. 0 0 0 0 13 0
184 207 3344 0 .. 0 0 0 0 9 0
185 208 3360 0 .. 0 0 0 0 14 0
186 211 3408 0 .. 0 0 0 0 5 0
187 212 3424 0 .. 0 0 0 0 16 0
188 214 3456 0 .. 0 0 0 0 11 0
189 217 3504 0 .. 0 0 0 0 6 0
190 219 3536 0 .. 0 0 0 0 13 0
191 222 3584 0 .. 0 0 0 0 7 0
192 223 3600 0 .. 0 0 0 0 15 0
193 225 3632 0 .. 0 0 0 0 8 0
194 228 3680 0 .. 0 0 0 0 9 0
195 230 3712 0 .. 0 0 0 0 10 0
196 232 3744 0 .. 0 0 0 0 11 0
197 234 3776 0 .. 0 0 0 0 12 0
198 235 3792 0 .. 0 0 0 0 13 0
199 236 3808 0 .. 0 0 0 0 14 0
200 238 3840 0 .. 0 0 0 0 15 0
201 254 4096 0 .. 0 0 0 0 1 0
202 ...
203
204 Overall the combined zspage chain size effect on zsmalloc pool configuration:::
205
206 pages per zspage number of size classes (clusters) huge size class watermark
207 4 69 3264
208 5 86 3408
209 6 93 3504
210 7 112 3584
211 8 123 3632
212 9 140 3680
213 10 143 3712
214 11 159 3744
215 12 164 3776
216 13 180 3792
217 14 183 3808
218 15 188 3840
219 16 191 3840
220
221
222 A synthetic test
223 ----------------
224
225 zram as a build artifacts storage (Linux kernel compilation).
226
227 * `CONFIG_ZSMALLOC_CHAIN_SIZE=4`
228
229 zsmalloc classes stats:::
230
231 class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
232
233 ...
234 Total 13 .. 51 413836 412973 159955 3
235
236 zram mm_stat:::
237
238 1691783168 628083717 655175680 0 655175680 60 0 34048 34049
239
240
241 * `CONFIG_ZSMALLOC_CHAIN_SIZE=8`
242
243 zsmalloc classes stats:::
244
245 class size 10% .... 100% obj_allocated obj_used pages_used pages_per_zspage freeable
246
247 ...
248 Total 18 .. 87 414852 412978 156666 0
249
250 zram mm_stat:::
251
252 1691803648 627793930 641703936 0 641703936 60 0 33591 33591
253
254 Using larger zspage chains may result in using fewer physical pages, as seen
255 in the example where the number of physical pages used decreased from 159955
256 to 156666, at the same time maximum zsmalloc pool memory usage went down from
257 655175680 to 641703936 bytes.
258
259 However, this advantage may be offset by the potential for increased system
260 memory pressure (as some zspages have larger chain sizes) in cases where there
261 is heavy internal fragmentation and zspool compaction is unable to relocate
262 objects and release zspages. In these cases, it is recommended to decrease
263 the limit on the size of the zspage chains (as specified by the
264 CONFIG_ZSMALLOC_CHAIN_SIZE option).
265
266 Functions
267 =========
268
269 .. kernel-doc:: mm/zsmalloc.c
270

3. 한국어 전문 번역

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

0-order page를 연결한 zspage

1-32

zsmalloc

이 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-220

Chain 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