Back to home page

OSCL-LXR

 
 

    


0001 .. _zsmalloc:
0002 
0003 ========
0004 zsmalloc
0005 ========
0006 
0007 This allocator is designed for use with zram. Thus, the allocator is
0008 supposed to work well under low memory conditions. In particular, it
0009 never attempts higher order page allocation which is very likely to
0010 fail under memory pressure. On the other hand, if we just use single
0011 (0-order) pages, it would suffer from very high fragmentation --
0012 any object of size PAGE_SIZE/2 or larger would occupy an entire page.
0013 This was one of the major issues with its predecessor (xvmalloc).
0014 
0015 To overcome these issues, zsmalloc allocates a bunch of 0-order pages
0016 and links them together using various 'struct page' fields. These linked
0017 pages act as a single higher-order page i.e. an object can span 0-order
0018 page boundaries. The code refers to these linked pages as a single entity
0019 called zspage.
0020 
0021 For simplicity, zsmalloc can only allocate objects of size up to PAGE_SIZE
0022 since this satisfies the requirements of all its current users (in the
0023 worst case, page is incompressible and is thus stored "as-is" i.e. in
0024 uncompressed form). For allocation requests larger than this size, failure
0025 is returned (see zs_malloc).
0026 
0027 Additionally, zs_malloc() does not return a dereferenceable pointer.
0028 Instead, it returns an opaque handle (unsigned long) which encodes actual
0029 location of the allocated object. The reason for this indirection is that
0030 zsmalloc does not keep zspages permanently mapped since that would cause
0031 issues on 32-bit systems where the VA region for kernel space mappings
0032 is very small. So, before using the allocating memory, the object has to
0033 be mapped using zs_map_object() to get a usable pointer and subsequently
0034 unmapped using zs_unmap_object().
0035 
0036 stat
0037 ====
0038 
0039 With CONFIG_ZSMALLOC_STAT, we could see zsmalloc internal information via
0040 ``/sys/kernel/debug/zsmalloc/<user name>``. Here is a sample of stat output::
0041 
0042  # cat /sys/kernel/debug/zsmalloc/zram0/classes
0043 
0044  class  size almost_full almost_empty obj_allocated   obj_used pages_used pages_per_zspage
0045     ...
0046     ...
0047      9   176           0            1           186        129          8                4
0048     10   192           1            0          2880       2872        135                3
0049     11   208           0            1           819        795         42                2
0050     12   224           0            1           219        159         12                4
0051     ...
0052     ...
0053 
0054 
0055 class
0056         index
0057 size
0058         object size zspage stores
0059 almost_empty
0060         the number of ZS_ALMOST_EMPTY zspages(see below)
0061 almost_full
0062         the number of ZS_ALMOST_FULL zspages(see below)
0063 obj_allocated
0064         the number of objects allocated
0065 obj_used
0066         the number of objects allocated to the user
0067 pages_used
0068         the number of pages allocated for the class
0069 pages_per_zspage
0070         the number of 0-order pages to make a zspage
0071 
0072 We assign a zspage to ZS_ALMOST_EMPTY fullness group when n <= N / f, where
0073 
0074 * n = number of allocated objects
0075 * N = total number of objects zspage can store
0076 * f = fullness_threshold_frac(ie, 4 at the moment)
0077 
0078 Similarly, we assign zspage to:
0079 
0080 * ZS_ALMOST_FULL  when n > N / f
0081 * ZS_EMPTY        when n == 0
0082 * ZS_FULL         when n == N