Swap: Difference between revisions

 
(17 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Category:Configuration]]
[[Category:Configuration]]


Swap provides additional virtual memory by extending physical RAM. This can be accomplished by using space on disk, such as [[#Swap file|swap file]] or [[#Swap partition|swap partition]], or through compression based methods like [[#Zram swap|zram]]. Additionally, [[#Zswap swap cache|zswap]] can act as a RAM-based compressed cache sitting in front of a traditional disk-based swap device.
Swap allows "cold" pages of virtual memory to be stored in places other than directly in the physical RAM, effectively allowing more pages to be stored. This can be accomplished by using space on disk, such as [[#Swap file|swap file]] or [[#Swap partition|swap partition]], or through compression based methods like [[#Zram swap|zram]]. Additionally, [[#Zswap swap cache|zswap]] can act as a RAM-based compressed cache sitting in front of a traditional disk-based swap device.


= Configuration =
= Configuration =
Line 28: Line 28:
}}
}}


This will create a 16GB swapfile at <code>/var/lib/swapfile</code>. The <code>size</code> value [https://search.nixos.org/options?show=swapDevices.*.size is specified in megabytes]
This will create a 16GB swapfile at <code>/var/lib/swapfile</code>. The <code>size</code> value [https://search.nixos.org/options?show=swapDevices.*.size is specified in megabytes]. This will cause a swap file to be generated and an entry to be set up in <code>/etc/fstab</code>.


== Swap partition ==
== Swap partition ==


Swap partitions are typically created during the initial disk partitioning phase of a NixOS installation. For instructions on creating swap partitions, see the relevant NixOS manual sections for [https://nixos.org/manual/nixos/stable/#sec-installation-manual-partitioning-UEFI UEFI]/[https://nixos.org/manual/nixos/stable/#sec-installation-manual-partitioning-MBR MBR] partition schemes and [https://nixos.org/manual/nixos/stable/#sec-installation-manual-partitioning-formatting formatting].
Swap partitions are typically created during the initial disk partitioning phase of a NixOS installation. For instructions on creating swap partitions, see the relevant NixOS manual sections for [https://nixos.org/manual/nixos/stable/#sec-installation-manual-partitioning-UEFI UEFI]/[https://nixos.org/manual/nixos/stable/#sec-installation-manual-partitioning-MBR MBR] partition schemes and [https://nixos.org/manual/nixos/stable/#sec-installation-manual-partitioning-formatting formatting].
Swap partitions can be defined in <code>configuration.nix</code> like above or (if GPT) be automatically discovered by <code>systemd-gpt-auto-generator(8)</code>. Using the former allows you to have some control over swap mounting options and to enable features such as encrypted swap.


== Zram swap ==
== Zram swap ==
Line 108: Line 110:
</syntaxhighlight>
</syntaxhighlight>


If you are using GPT partitioning tables, <code>systemd-gpt-auto-generator(8)</code> will still mount your swap partition automatically. You must therefore turn on attribute 63 ("no automount") on ''each'' swap partition partition in the partition table. This can be done with gptfdisk or similar:
If you are using GPT partitioning tables, <code>systemd-gpt-auto-generator(8)</code> will still mount your swap partition automatically. You must therefore turn on attribute 63 ("no-auto") on ''each'' swap partition partition in the partition table. This can be done with gptfdisk or similar:


<syntaxhighlight lang="console">
<syntaxhighlight lang="console">
Line 127: Line 129:


= Tips and Tricks =
= Tips and Tricks =
== Mount options ==
=== discard ===
Solid state drives have fast random access times, which make them great for swap if you ignore the limited lifespan. Enabling TRIM (discard) on the swap files can help avoid unnecessary copy actions on the SSD, reducing wear and potentially helping increase performance.
<syntaxhighlight lang="nix">
swapDevices = [{
  device = "/dev/sdXY";
  options = [ "discard" ]; # equivalent to swapon --discard
}];
</syntaxhighlight>
A lower-impact option is <code>"discard=once"</code>, which runs discard exactly once when the swap is enabled, but does not continually issue discard commands as pages are being overwritten. This could make more sense depending on your hardware.
<code>systemd-gpt-auto-generator(8)</code> does not automatically enable <code>discard</code>. Also, never enable <code>discard</code> on mdadm RAID setups, as ArchWiki reports that it causes lockup.


== Encrypt swap with random key ==
== Encrypt swap with random key ==


Swap can be automatically encrypted with a new key on every boot. This can be used to simplify certain disk layouts, such as securing a swap file on a filesystem partition without  an encryption container (such as LUKS).
Because data from memory is evicted into swap, any secret data in memory can also end up in swap. Because the disks backing the swap is often nonvolatile (data is not lost after power cut), this can represent another way for data to end up in the wrong hands if you computer is seized.
 
By encrypting the swap with a random key kept in memory, we make sure that the contents of the swap become unreadable as soon as the data in memory has been lost. NixOS contains a handy helper to help you do this, generating a new key on each boot:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
swapDevices = [{
swapDevices = [{
   device = "/dev/sdXY";
   device = "/dev/disk/by-partuuid/aaaaaaaaa-bbbb-cccc-dddd-0123456789ab";
   randomEncryption.enable = true;  
   randomEncryption.enable = true;  
}];
}];
</syntaxhighlight>
</syntaxhighlight>
The selected device will have all its content made unusuable at every boot. Using a partuuid or partlabel is recommended because it is less subject to change when the overall partition scheme changes.
If you want to use TRIM, set <code>randomEncryption.allowDiscards</code> in addition to the <code>options</code>. This has the security implication of:
* telling whoever gets ahold of your swap drive which parts are being actually used (bad),
* telling your SSD to not give out the data in unused parts and to not try to keep them around during garbage collection (good).
You will need to weigh between the two.
Using a random key makes hibernation impossible. If you want to use hibernation, use a regular [[Full Disk Encryption]] (or partial disk encryption with LUKS) scheme with an unchanging key.


== Adjusting swap usage behaviour ==
== Adjusting swap usage behaviour ==


[https://docs.kernel.org/admin-guide/sysctl/vm.html#swappiness Swappiness] controls how aggressibely swap space is used. By default, Linux uses a swappiness value of 60. Higher values will make the kernel prefer swapping out idle processes sooner. Conversely lower values will try to avoid swapping as much as possible, keeping processes in RAM unless absolutely necessary. An optimal value is workload dependent and will will require experimentation.
[https://docs.kernel.org/admin-guide/sysctl/vm.html#swappiness Swappiness] controls how aggressibely swap space is used, specifically how to free up memory when needed. By default, Linux uses a swappiness value of 60. Higher values will make the kernel prefer swapping out idle processes over dropping caches. Conversely lower values will try to avoid swapping as much as possible, keeping processes in RAM unless absolutely necessary. An optimal value is workload dependent and will will require experimentation.


{{file|/etc/nixos/configuration.nix|nix|
{{file|/etc/nixos/configuration.nix|nix|
Line 151: Line 181:
}}
}}


You can see your current swappiness level by <code>cat /proc/sys/vm/swappiness</code>.
You can see your current swappiness level by <code>cat /proc/sys/vm/swappiness</code>. The lowest accepted value is 0 while the maximum value is 200. The lowest sane value is 1 (0 causes the system to not scan for unused anonymous pages, i.e. memory freed by processes, at all).
 
For more on tuning the swap, start with [https://wiki.archlinux.org/title/Swap#swappiness ArchWiki]'s description.


== ZFS and swap ==
== ZFS and swap ==