Monday, 31 March 2014

Using zram for memory compression on Gentoo

After reading an excellent compression on LWN about memory compression in Linux kernel and learning from a Google engineer that they employ zram to increase their workstation available memory (on top of the installed physical 48 GB ...), I've decided to give it a go. There are currently three different algorithms for memory compression being trialed in the Linux kernel, of those, zram is the simplest, but also the most mature - it's also battle tested, as it is enabled by default e.g. on Google Chromebooks. It's also available as an option in Android 4.4

zram works by presenting itself to the kernel as a swap device, while it is in fact backed by RAM. It has a fixed compression ratio of 50% (or, to be more exact, swapped out pages are either stored two-in-one for actual RAM page used or one-in-one if for some reason they don't compress). This simplifies access, keeping page offsets predicatable. A recommended configuration reserves up to 100% of physical RAM for compressed access - this memory will be released back when the memory pressure subsides. This also assumes the pessimistic scenario of incompressible pages - in practice, the zram devices should not take much more than 50% of their advertised capacity, resulting in 150% potential memory load before swapping would need to occur.

Configuration starts with enabling the kernel module:

Device Drivers  --->
    [*] Staging drivers --->
        <M> Compressed RAM block device support

This is done as a module, so that configuration can be easily changed via /etc/modprobe.d/zram.conf:

options zram num_devices=3

I've got the module set to auto-load via /etc/modules-load.d/zram.conf containing just a single line:

zram

Also needed is an entry for udev telling it how to handle zram block devices and setting their size (in /etc/udev/rules.d/10-zram.rules):

KERNEL=="zram[0-9]*", SUBSYSTEM=="block", DRIVER=="", ACTION=="add", ATTR{disksize}=="0", ATTR{disksize}="2048M", RUN+="/sbin/mkswap $env{DEVNAME}"

And the last step is an /etc/fstab entry so that those block devices are actually used:

/dev/zram0  none  swap  sw,pri=16383  0 0
/dev/zram1  none  swap  sw,pri=16383  0 0
/dev/zram2  none  swap  sw,pri=16383  0 0
/dev/zram3  none  swap  sw,pri=16383  0 0

I've seen guides recommending creation of ext4 volumes on zram devices for temporary folders. I would not advise that. Instead, create a standard tmpfs volume, with the required capacity, which will result in better performance - as unused zram device will release the memory back to the kernel.

I've been using this setup since November and haven't had any issues with it. I highly recommend enabling this on your workstation as well - after all, there's no such thing as too much RAM.