Zswap
zswap is a Linux kernel module that facilitates swap page caching using compressed memory. Swap pages going to and from swap devices can be cached using a up to 3:1 compressed memory as cache storage. Compressed memory pages are only swapped to disk when the memory set aside for zswap is full. This is specially useful for systems without a fast SSD since swapping to and from disk takes time. The trade-off to be aware of is that the memory pool set aside for zswap will not be available to regular applications when it is used which means that the total system memory available for applications is reduced. zswap does not use memory if there is nothing in the cache.
zswap is a swap cache meant to be used with a regular swap device. See zram if you want to make a memory swap device. zswap is not, like the name sounds like, something that creates a memory backed swap device. It is purely a cache for swap devices on disk (or even memory-backed swap devices created using zram).
Performance Implications[edit]
Using a zswap cache can have a negative impact, not a positive one, on longer memory-constrained compile times. Having a large zram swap device will, in contrast, help, while a smaller zram swap devices appear to hamper performance. Take note of the difference between the three different allocators a zswap cache can use, there is a big practical difference between zbud
, zsmalloc
and z3fold
RAM | zram swap | zswap (cache) | compression | time | difference |
---|---|---|---|---|---|
7 GiB | none | none | none | 29h 9m (1748m48.292s) | Baseline |
7 GiB | GiB | none | lzo-rle | 29h 14m 1753m57.703s | +5 minutes |
7 GiB | 1 GiB | none | zstd | 30h 23m (1823m56.761s) | +1 hours 15 minutes |
7 GiB | 2 GiB | none | zstd | 28h 46m (1725m45.160s) | -23 minutes |
7 GiB | 3.5 GiB (50% of physical RAM) |
none | lzo-rle | 27h 25m (1645m13.886s) | -1 hour 44 minutes |
7 GiB | 3.5 GiB (50% of physical RAM) |
none | zstd | 27h 28m (1647m58.215s) | -1 hour 41 minutes |
7 GiB | none | 10% (700 MiB) zbud |
zstd | 29h m4hm (1782m4.096s) | + 33 minutes |
7 GiB | none | 10% (700 MiB) z3fold |
zstd | 30h 18m (1818m52.867s) | +1 hour 10 minutes |
7 GiB | none | 10% (700 MiB) zsmalloc |
zstd | 28h 43m (1723m9.704s) | -26 minutes |
7 GiB | none | 20% (1400 MiB) z3fold |
zstd | 30h 18m (1818m55.137s) | +1 hour 10 minutes |
The properties z3fold
has would make you'd think it's the the best choice. It's not. It's the worst.
Configuration[edit]
The max_pool_percent
option tells zswap how much memory it should use to cache pages going to and from swap. It is set as a percentage of system RAM. 10% on a machine with 32 GiB RAM allocates more RAM to zswap than a machine with 2 GiB RAM has.
Memory set aside for zswap is not used until the swap cache is filled. It remains available until swap pages actually fill the cache.
Choosing the "right" number may be hard. A high number means you get a bigger cache which makes swapping faster and more responsive, which is good. There is also a penalty which can hamper performance: Less memory is available to actively running processes when the swap cache is filled. If you have 8 GiB total and you make a 3 GiB zswap cache with zstd and your machine starts swapping hard and the cache is filled you're left with either 8-1=7 GiB
or 8-1.5=6.5 GiB
memory available to running applications. How much memory a 3 GiB zswap cache actually uses will depend on the compression algorithm and the allocator. Both are configurable.
A simple way to enable zswap swap cache is to create simple script which configures it and a basic systemd service file that runs it at boot-time.
#!/bin/sh
if [ "${1}" == "off" ];then
echo N >/sys/module/zswap/parameters/enabled
exit 0
fi
# We must have the zswap technology so RAM is
# compressed to a RAM pool before they are swapped
echo 1 > /sys/module/zswap/parameters/enabled
# % of total system memory can be used for compressed
# swap pages. These are sent to disk when zswap pool
# is full.
echo 10 > /sys/module/zswap/parameters/max_pool_percent
## Use this with kernels prior to 5.1
# echo lz4 > /sys/module/zswap/parameters/compressor
## lzo-rle is the best option for Linux 5.1-5.7
#echo lzo-rle > /sys/module/zswap/parameters/compressor
## Linux 5.7+ can use ZSTD to compress zswap
echo zstd > /sys/module/zswap/parameters/compressor
# Faster than any of the alternatives.
echo zsmalloc > /sys/module/zswap/parameters/zpool
The above script can be started at boot by creating a very simple systemd service file:
[Unit]
Description=Configures zswap cache
After=local-fs.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/zswapcache-on
ExecStop=/usr/local/bin/zswapcache-on off
RemainAfterExit=yes
[Install]
WantedBy = multi-user.target
Make the script executable with
chmod +x /usr/local/bin/zswapcache-on
then reload the systemd services with
systemctl daemon-reload
and you will be able start and enable the service with
systemctl enable --now zswapcache
Compression algorithms[edit]
zstd
is the by far best-compressing algorithm. It will do something in the neighborhood of 5:1 compression of typical swap pages. It is NOT available in kernels <=5.7.
lzo-rle
is the second best choice. It too is unavailable in older kernels. Not entirely sure when it was introduced, perhaps Linux 5.1. 4.xx kernels do not have this technology.
lzo
is the best choice if neither zstd or lzo-rle are available.
Allocators[edit]
There are three zpool allocators available: zbud, zsmalloc and z3fold. zbud supports page eviction, it can throw old pages out if new ones are needed. zsmalloc can not do that, it has to reject new pages if the pool is full. The kernel documentation does not say if z3fold can evict or not. z3fold is only available in <=4.8 Linux kernels.
- zbud will try to compress 2:1 and mostly do it. You get close to 2 GiB memory in a 1 GiB zswap memory pool using zbud.
- zsmalloc has a "more complex compressed page storage method, and it can achieve greater storage densities" according to the kernel documentation. How much better compression it provides is not detailed. zsmalloc is, in practice, the fastest allocator.
- z3fold is similar to zbud but it can compress 3:1, not just 2:1. It is a fairly recent addition to the Linux kernel so you may not have it available if you are using a LTS distribution. z3fold is, in practice, the slowest allocator.
Enable comment auto-refresher
Anonymous (36c36234d6)
Permalink |