zsmalloc¶
This allocator is designed for use with zram. Thus, the allocator issupposed to work well under low memory conditions. In particular, itnever attempts higher order page allocation which is very likely tofail 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 pagesand links them together using various ‘struct page’ fields. These linkedpages act as a single higher-order page i.e. an object can span 0-orderpage boundaries. The code refers to these linked pages as a single entitycalled zspage.
For simplicity, zsmalloc can only allocate objects of size up to PAGE_SIZEsince this satisfies the requirements of all its current users (in theworst case, page is incompressible and is thus stored “as-is” i.e. inuncompressed form). For allocation requests larger than this size, failureis returned (see zs_malloc).
Additionally, zs_malloc() does not return a dereferenceable pointer.Instead, it returns an opaque handle (unsigned long) which encodes actuallocation of the allocated object. The reason for this indirection is thatzsmalloc does not keep zspages permanently mapped since that would causeissues on 32-bit systems where the VA region for kernel space mappingsis very small. So, before using the allocating memory, the object has tobe mapped using zs_map_object() to get a usable pointer and subsequentlyunmapped using zs_unmap_object().
stat¶
With CONFIG_ZSMALLOC_STAT, we could see zsmalloc internal information via/sys/kernel/debug/zsmalloc/<username>. Here is a sample of stat output:
# cat /sys/kernel/debug/zsmalloc/zram0/classesclass size almost_full almost_empty obj_allocated obj_used pages_used pages_per_zspage ... ... 9 176 0 1 186 129 8 4 10 192 1 0 2880 2872 135 3 11 208 0 1 819 795 42 2 12 224 0 1 219 159 12 4 ... ...
- class
- index
- size
- object size zspage stores
- almost_empty
- the number of ZS_ALMOST_EMPTY zspages(see below)
- almost_full
- the number of ZS_ALMOST_FULL zspages(see below)
- 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
We assign a zspage to ZS_ALMOST_EMPTY fullness group when n <= N / f, where
- n = number of allocated objects
- N = total number of objects zspage can store
- f = fullness_threshold_frac(ie, 4 at the moment)
Similarly, we assign zspage to:
- ZS_ALMOST_FULL when n > N / f
- ZS_EMPTY when n == 0
- ZS_FULL when n == N