nixos: Add zram swap module

This allows you to use the Linux kernel's built-in compressed memory as
swap space functionality.

It is recommended to enable only for kernel 3.14 (which is when zram came out of
the staging drivers area) or higher.

+139
+138
nixos/modules/config/zram.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + let 6 + 7 + cfg = config.zramSwap; 8 + 9 + devices = map (nr: "zram${toString nr}") (range 0 (cfg.numDevices - 1)); 10 + 11 + modprobe = "${config.system.sbin.modprobe}/sbin/modprobe"; 12 + 13 + in 14 + 15 + { 16 + 17 + ###### interface 18 + 19 + options = { 20 + 21 + zramSwap = { 22 + 23 + enable = mkOption { 24 + default = false; 25 + type = types.bool; 26 + description = '' 27 + Enable in-memory compressed swap space provided by the zram kernel 28 + module. It is recommended to enable only for kernel 3.14 or higher. 29 + ''; 30 + }; 31 + 32 + numDevices = mkOption { 33 + default = 4; 34 + type = types.int; 35 + description = '' 36 + Number of zram swap devices to create. It should be equal to the 37 + number of CPU cores your system has. 38 + ''; 39 + }; 40 + 41 + memoryPercent = mkOption { 42 + default = 50; 43 + type = types.int; 44 + description = '' 45 + Maximum amount of memory that can be used by the zram swap devices 46 + (as a percentage of your total memory). Defaults to 1/2 of your total 47 + RAM. 48 + ''; 49 + }; 50 + 51 + priority = mkOption { 52 + default = 5; 53 + type = types.int; 54 + description = '' 55 + Priority of the zram swap devices. It should be a number higher than 56 + the priority of your disk-based swap devices (so that the system will 57 + fill the zram swap devices before falling back to disk swap). 58 + ''; 59 + }; 60 + 61 + }; 62 + 63 + }; 64 + 65 + config = mkIf cfg.enable { 66 + 67 + system.requiredKernelConfig = with config.lib.kernelConfig; [ 68 + (isModule "ZRAM") 69 + ]; 70 + 71 + # Disabling this for the moment, as it would create and mkswap devices twice, 72 + # once in stage 2 boot, and again when the zram-reloader service starts. 73 + # boot.kernelModules = [ "zram" ]; 74 + 75 + boot.extraModprobeConfig = '' 76 + options zram num_devices=${toString cfg.numDevices} 77 + ''; 78 + 79 + services.udev.extraRules = '' 80 + KERNEL=="zram[0-9]*", ENV{SYSTEMD_WANTS}="zram-init-%k.service", TAG+="systemd" 81 + ''; 82 + 83 + systemd.services = 84 + let 85 + createZramInitService = dev: 86 + nameValuePair "zram-init-${dev}" { 87 + description = "Init swap on zram-based device ${dev}"; 88 + bindsTo = [ "dev-${dev}.swap" ]; 89 + after = [ "dev-${dev}.device" "zram-reloader.service" ]; 90 + requires = [ "dev-${dev}.device" "zram-reloader.service" ]; 91 + before = [ "dev-${dev}.swap" ]; 92 + requiredBy = [ "dev-${dev}.swap" ]; 93 + serviceConfig = { 94 + Type = "oneshot"; 95 + RemainAfterExit = true; 96 + ExecStop = "${pkgs.stdenv.shell} -c 'echo 1 > /sys/class/block/${dev}/reset'"; 97 + }; 98 + script = '' 99 + set -u 100 + set -o pipefail 101 + 102 + PATH=${pkgs.procps}/bin:${pkgs.gnugrep}/bin:${pkgs.gnused}/bin 103 + 104 + # Calculate memory to use for zram 105 + totalmem=$(free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/ *.*//') 106 + mem=$(((totalmem * ${toString cfg.memoryPercent} / 100 / ${toString cfg.numDevices}) * 1024)) 107 + 108 + echo $mem > /sys/class/block/${dev}/disksize 109 + ${pkgs.utillinux}/sbin/mkswap /dev/${dev} 110 + ''; 111 + restartIfChanged = false; 112 + }; 113 + in listToAttrs ((map createZramInitService devices) ++ [(nameValuePair "zram-reloader" 114 + { 115 + description = "Reload zram kernel module when number of devices changes"; 116 + serviceConfig = { 117 + Type = "oneshot"; 118 + RemainAfterExit = true; 119 + ExecStartPre = "${modprobe} -r zram"; 120 + ExecStart = "${modprobe} zram"; 121 + ExecStop = "${modprobe} -r zram"; 122 + }; 123 + restartTriggers = [ cfg.numDevices ]; 124 + restartIfChanged = true; 125 + })]); 126 + 127 + swapDevices = 128 + let 129 + useZramSwap = dev: 130 + { 131 + device = "/dev/${dev}"; 132 + priority = cfg.priority; 133 + }; 134 + in map useZramSwap devices; 135 + 136 + }; 137 + 138 + }
+1
nixos/modules/module-list.nix
··· 20 20 ./config/timezone.nix 21 21 ./config/unix-odbc-drivers.nix 22 22 ./config/users-groups.nix 23 + ./config/zram.nix 23 24 ./hardware/all-firmware.nix 24 25 ./hardware/cpu/intel-microcode.nix 25 26 ./hardware/cpu/amd-microcode.nix