Swap

From Gentoo Wiki
(Redirected from Memory paging)
Jump to:navigation Jump to:search
This page contains changes which are not marked for translation.
Resources
This article has some todo items:
  • remove swap files, btrfs swapfile note
Not to be confused with Zswap.


In the Linux/Unix world, the term swap is generally used as a synonym for memory paging. Swap refers to both the act of moving memory pages between memory and a secondary storage.

Linux can use a combination of swap areas - multiple swap devices and/or swap files together. It is also possible to assign different priorities to swap areas.

However, swap space may not be necessary at all depending on the requirements for the system in question. For example, a laptop that suspends to disk (hibernation) requires all pages in memory to be stored to disk, so swap is necessary in this case. Server systems equipped with large amount of memory running at a constant load might not require swap at all. For further details, see the dedicated Knowledge Base article.

Swap partition

As best practice, the Gentoo Handbook recommends, as part of the installation process, creating a swap partition with a size of twice the available system memory[1].

Swap partitions can be created and activated at any time as long as partitions are available and formatted correctly.

Tip
Nowadays, having systems with plenty of memory, it may be sufficient to create a swap partition smaller than the available memory. When using hibernation, storing a compressed RAM image inside the swap partition, it's a good idea having a swap partition with the size of the installed memory.

Creation

Presuming /dev/sda2 is the partition available to be used for swap:

root #mkswap /dev/sda2 # Format the partition for swap.
root #swapon /dev/sda2 # Activate the swap partition.

Review the activated swaps with the swapon command:

root #swapon --show

To avoid manually activating the swap file across reboots, append a line (adjusting the path as necessary) to fstab:

FILE /etc/fstab
/dev/sda2 none swap sw 0 0

Encrypted swap with hibernate option

Assuming the desired goal is a LUKS encrypted swap partition with the ability to still be able to perform hibernate (a.k.a. suspend to disk). The encrypted swap partition needs a known LUKS-key (keyfile, password, etc.). The user will be asked to enter the password from a very early phase of the boot process. The kernel then has to decide whether to regularly boot the system or to load a hibernated RAM image from SWAP – if if the system was hibernated in the previously power state.

The creation of a LUKS encrypted swap partition is not different to any other LUKS encrypted partition, described in creating an encrypted storage platform. Use mkswap instead of mkfs.* to the LUKS encrypted partition to create SWAP. The UUID (i.e. 01b37ea8-74a5-4526-85c7-9fdf6dad34cb), created when formatting as swap, is needed for the next step:

Tell the bootloader (GRUB) where to resume from if hibernated:

FILE /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="resume=UUID=01b37ea8-74a5-4526-85c7-9fdf6dad34cb"

In addition (when using OpenRC with dracut, systemd is presumed to be now used for this section of the guide) dracut will need to be told the major and minor number of the associated LUKS device, so it can create an appropriate initrd:

root #lsblk
..
└─sdb1                                          8:22   0    32G  0 part   
 └─luks-cc166689-4246-41ae-86e8-84705b81ecc2  253:1    0    32G  0 crypt [SWAP]
root #echo 253:1 > /sys/power/resume
Note
The default value is 0:0. echo this in again to deactivate hibernation.
Warning
Ensure LUKS UUID (cc166689-4246-41ae-86e8-84705b81ecc2) and the SWAP UUID (01b37ea8-74a5-4526-85c7-9fdf6dad34cb) are not confused!

Finally, the initrd needs to be updated with this changes:

root #dracut --hostonly --force

Do not forget the regular configuration of SWAP in /etc/fstab and restart the system afterwards.

FILE /etc/fstab
# /dev/sdb1 (SWAP) 
UUID=01b37ea8-74a5-4526-85c7-9fdf6dad34cb               none            swap    sw      0 0
Note
If a LUKS encrypted SWAP using dmcrypt is already setup by including a configuration in /etc/conf.d/dmcrypt, it will be obsolete, since this LUKS device will now be opened earlier with the help of the dracut generated initrd.

Using full disk encryption

When already using full disk encryption with LUKS, a decryption password prompt will appear twice when booting; once to enter the LUKS-key for the system's root partition (as before) and once to decrypt the SWAP partition. It is possible to just decrypt the root partition and then use a LUKS keyfile, stored on the just now decrypted root partition, to decrypt the SWAP partition automatically. Details and an easy example how to do this within /etc/default/grub, can be found on kernel.org.

Swap files

In order to work around the more ridged constraints of disk partitions, an alternative is to use swap as an on-disk file. Files have the ability to be located inside disk partitions. This allows the system administrator the flexibility to resize or move the swap space as necessary to meet the demands of the system without having to open a partitioning tool.

Creation

Begin by allocating a new file used for the backing store of the swapfile, the size of this file will be the size of the swap space. Standard utilities can be used for this purpose such as fallocate from sys-apps/util-linux:

root #fallocate -l 12GiB swapfile # Create the file.
root #chmod 600 swapfile # Restrict security on the file to root access only.
Note
If the partition the swapfile is located on is using btrfs, swapon will fail unless the swap file is in its own subvolume and copy-on-write and compression are disabled for the swapfile[2]. Assuming a 4GB swap file, the steps would be as follows:
root # btrfs subvolume create swap_vol
root # chattr +C swap_vol
root # fallocate -l 4G swap_vol/swapfile
root # chmod 600 swap_vol/swapfile

Now initialize and turn the swapfile on:

root #mkswap swapfile # Format the file swap.
root #swapon swapfile # Activate the swap file.

It's also possible to review the system swaps with the swapon command:

root #swapon --show

To avoid manually activating the swap file across reboots, append a line (adjusting the path as necessary) to fstab:

FILE /etc/fstab
/swapfile none swap sw 0 0

Encrypted swap file

It is best practice to encrypt swap files.

Creation

To create a 2 GiB encrypted swap file in the /opt directory, run:

root #cd /opt
root #fallocate -l 2GiB swapfile
root #chmod 600 swapfile
root #cryptsetup --type plain -d /dev/urandom open swapfile cryptswap
root #mkswap /dev/mapper/cryptswap
root #swapon /dev/mapper/cryptswap
root #swapon --show
FILE /etc/fstab
/dev/mapper/cryptswap none swap sw 0 0

Activation (systemd)

Note
Make sure systemd is compiled with cryptsetup support, otherwise /etc/crypttab will not be read.
FILE /etc/crypttab
cryptswap /opt/swapfile /dev/urandom swap

Activation (OpenRC)

Warning
The OpenRC dm-crypt daemon uses the aes-cbc-plain cipher by default, which is vulnerable [3] . Therefore, the options must be specified to use the aes-cbc-essiv cipher instead.

Use this command to check which cipher is being used:

root #dmsetup table cryptswap
FILE /etc/conf.d/dmcrypt
swap=cryptswap
source=/opt/swapfile
options='--type plain --key-file /dev/urandom'

Enable the dmcrypt service:

root #rc-update add dmcrypt boot

If the dm-crypt daemon fails to create the swap at boot, for example, with the following error:

mkswap: unable to erase bootbits sectors

the swap can be created manually. Disable the dm-crypt daemon and revert the changes made to /etc/fstab and /etc/conf.d/dmcrypt. Create the /etc/local.d files:

FILE /etc/local.d/swap.start
cryptsetup --type plain -d /dev/urandom open /opt/swapfile cryptswap
mkswap /dev/mapper/cryptswap
swapon /dev/mapper/cryptswap
FILE /etc/local.d/swap.stop
swapoff /dev/mapper/cryptswap
cryptsetup close cryptswap

And make the scripts executable:

root #chmod +x /etc/local.d/swap.start
root #chmod +x /etc/local.d/swap.stop

The swap will be created after a reboot.

OpenRC configuration

When using swap files which are not on the root filesystem, the service ordering in OpenRC should be changed via /etc/conf.d/swap:

FILE /etc/conf.d/swap
# If you are only using local swap partitions, you should not change
# this file. Otherwise, you need to uncomment the below rc_before line
# followed by the appropriate rc_need line.
rc_before="!localmount"
#
# If you are using swap files stored on local file systems, uncomment
# this line.
rc_need="localmount"
#
# If you are using swap files stored on network file systems or swap
# partitions stored on network block devices such as iSCSI, uncomment
# this line.
#rc_need="netmount"

Performance tuning

Prioritization

It is possible to prioritize different swap areas by assigning priority (an integer from 0 to 32767). Higher-priority swap areas are used first. Lower-priority areas are used after exhausting the higher ones. Areas having the same priority are used in a round-robin fashion[4].

The priority can be used for systems using a combination of fast (ZRAM or NVMe-based devices) and slow swap areas (HDD-based devices) to prioritize the former before the latter ones.

For example, prioritizing a fast swap device /dev/nvme0n1 before a regular swap file /swapfile using /etc/fstab:

FILE /etc/fstabSwap prioritization example
/dev/nvme0n1      none        swap        sw,pri=16383        0 0
/swapfile         none        swap        sw,pri=1            0 0

Swappiness

Kernel allows tuning of the swap usage via sysctl parameters allowing to adapt the swapping for various workloads.

The vm.swappiness parameter controls the ratio between kernel willingness to reclaim file-backed ("memory cached" parts files) and anonymous memory pages (application heap and stack) back to their respective backing storage. The value range on recent kernels is 0-200, while the default is 60[5]. Values lower than the default represent a preference of keeping the application-related anonymous memory pages in memory at the expense of file-backed pages and vice versa.

The current value can be displayed by:

user $sysctl vm.swappiness
vm.swappiness = 60

The desired swappiness value can be persistently set via:

FILE /etc/sysctl.d/90-swappiness.confReduced system swappiness
vm.swappiness=20

See also

  • Filesystem — a means to organize data to be retained after a program terminates.
  • Zram — a Linux kernel feature and userspace tools for creating compressible RAM-based block devices.
  • Zswap — a lightweight compressed cache for swap pages.

External resources

References