Zswap

From LinuxReviews
Jump to navigationJump to search
Tux-000f.svg

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

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

Chromium 85 Compile times
Athlon 5350 APU, 8 (7) GiB RAM
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

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.

File: /usr/local/bin/zswapcache-on
#!/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:

File: /etc/systemd/system/zswapcache.service
[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

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

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.

See also

  • zram can be used to create compressed memory-backed devices such as a memory-compressed swap device. zram allows you to create an actual swap device, not just a swap drive cache.

avatar

Anonymous user #1

6 months ago
Score 0++
I guess benchmark results depends on vm.* sysctl parameters such as swappiness, dirty_ratio, or so..
avatar

Anonymous user #1

6 months ago
Score 0++

Also simplest way to enable ZRAM is to use kernel command line:

zswap.enabled=1 zswap.zpool=..
Add your comment
LinuxReviews welcomes all comments. If you do not want to be anonymous, register or log in. It is free.