mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-12-29 23:07:36 +03:00
Merge pull request #52991 from danbst/zram-zstd
zramSwap: allow configure compression algorithm + cleanups
This commit is contained in:
commit
ab31b13401
@ -408,6 +408,21 @@
|
|||||||
from nixpkgs due to the lack of maintainers.
|
from nixpkgs due to the lack of maintainers.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
It is possible now to uze ZRAM devices as general purpose ephemeral block devices,
|
||||||
|
not only as swap. Using more than 1 device as ZRAM swap is no longer recommended,
|
||||||
|
but is still possible by setting <literal>zramSwap.swapDevices</literal> explicitly.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Default algorithm for ZRAM swap was changed to <literal>zstd</literal>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Changes to ZRAM algorithm are applied during <literal>nixos-rebuild switch</literal>,
|
||||||
|
so make sure you have enough swap space on disk to survive ZRAM device rebuild. Alternatively,
|
||||||
|
use <literal>nixos-rebuild boot; reboot</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
@ -6,10 +6,27 @@ let
|
|||||||
|
|
||||||
cfg = config.zramSwap;
|
cfg = config.zramSwap;
|
||||||
|
|
||||||
devices = map (nr: "zram${toString nr}") (range 0 (cfg.numDevices - 1));
|
# don't set swapDevices as mkDefault, so we can detect user had read our warning
|
||||||
|
# (see below) and made an action (or not)
|
||||||
|
devicesCount = if cfg.swapDevices != null then cfg.swapDevices else cfg.numDevices;
|
||||||
|
|
||||||
|
devices = map (nr: "zram${toString nr}") (range 0 (devicesCount - 1));
|
||||||
|
|
||||||
modprobe = "${pkgs.kmod}/bin/modprobe";
|
modprobe = "${pkgs.kmod}/bin/modprobe";
|
||||||
|
|
||||||
|
warnings =
|
||||||
|
assert cfg.swapDevices != null -> cfg.numDevices >= cfg.swapDevices;
|
||||||
|
flatten [
|
||||||
|
(optional (cfg.numDevices > 1 && cfg.swapDevices == null) ''
|
||||||
|
Using several small zram devices as swap is no better than using one large.
|
||||||
|
Set either zramSwap.numDevices = 1 or explicitly set zramSwap.swapDevices.
|
||||||
|
|
||||||
|
Previously multiple zram devices were used to enable multithreaded
|
||||||
|
compression. Linux supports multithreaded compression for 1 device
|
||||||
|
since 3.15. See https://lkml.org/lkml/2014/2/28/404 for details.
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -24,9 +41,11 @@ in
|
|||||||
default = false;
|
default = false;
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
description = ''
|
description = ''
|
||||||
Enable in-memory compressed swap space provided by the zram kernel
|
Enable in-memory compressed devices and swap space provided by the zram
|
||||||
module.
|
kernel module.
|
||||||
See https://www.kernel.org/doc/Documentation/blockdev/zram.txt
|
See <link xlink:href="https://www.kernel.org/doc/Documentation/blockdev/zram.txt">
|
||||||
|
https://www.kernel.org/doc/Documentation/blockdev/zram.txt
|
||||||
|
</link>.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -34,7 +53,19 @@ in
|
|||||||
default = 1;
|
default = 1;
|
||||||
type = types.int;
|
type = types.int;
|
||||||
description = ''
|
description = ''
|
||||||
Number of zram swap devices to create.
|
Number of zram devices to create. See also
|
||||||
|
<literal>zramSwap.swapDevices</literal>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = mkOption {
|
||||||
|
default = null;
|
||||||
|
example = 1;
|
||||||
|
type = with types; nullOr int;
|
||||||
|
description = ''
|
||||||
|
Number of zram devices to be used as swap. Must be
|
||||||
|
<literal><= zramSwap.numDevices</literal>.
|
||||||
|
Default is same as <literal>zramSwap.numDevices</literal>, recommended is 1.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -44,7 +75,8 @@ in
|
|||||||
description = ''
|
description = ''
|
||||||
Maximum amount of memory that can be used by the zram swap devices
|
Maximum amount of memory that can be used by the zram swap devices
|
||||||
(as a percentage of your total memory). Defaults to 1/2 of your total
|
(as a percentage of your total memory). Defaults to 1/2 of your total
|
||||||
RAM.
|
RAM. Run <literal>zramctl</literal> to check how good memory is
|
||||||
|
compressed.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -58,12 +90,26 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
algorithm = mkOption {
|
||||||
|
default = "zstd";
|
||||||
|
example = "lzo";
|
||||||
|
type = with types; either (enum [ "lzo" "lz4" "zstd" ]) str;
|
||||||
|
description = ''
|
||||||
|
Compression algorithm. <literal>lzo</literal> has good compression,
|
||||||
|
but is slow. <literal>lz4</literal> has bad compression, but is fast.
|
||||||
|
<literal>zstd</literal> is both good compression and fast.
|
||||||
|
You can check what other algorithms are supported by your zram device with
|
||||||
|
<programlisting>cat /sys/class/block/zram*/comp_algorithm</programlisting>
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
inherit warnings;
|
||||||
|
|
||||||
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
||||||
(isModule "ZRAM")
|
(isModule "ZRAM")
|
||||||
];
|
];
|
||||||
@ -85,25 +131,25 @@ in
|
|||||||
createZramInitService = dev:
|
createZramInitService = dev:
|
||||||
nameValuePair "zram-init-${dev}" {
|
nameValuePair "zram-init-${dev}" {
|
||||||
description = "Init swap on zram-based device ${dev}";
|
description = "Init swap on zram-based device ${dev}";
|
||||||
bindsTo = [ "dev-${dev}.swap" ];
|
|
||||||
after = [ "dev-${dev}.device" "zram-reloader.service" ];
|
after = [ "dev-${dev}.device" "zram-reloader.service" ];
|
||||||
requires = [ "dev-${dev}.device" "zram-reloader.service" ];
|
requires = [ "dev-${dev}.device" "zram-reloader.service" ];
|
||||||
before = [ "dev-${dev}.swap" ];
|
before = [ "dev-${dev}.swap" ];
|
||||||
requiredBy = [ "dev-${dev}.swap" ];
|
requiredBy = [ "dev-${dev}.swap" ];
|
||||||
|
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
ExecStop = "${pkgs.runtimeShell} -c 'echo 1 > /sys/class/block/${dev}/reset'";
|
ExecStop = "${pkgs.runtimeShell} -c 'echo 1 > /sys/class/block/${dev}/reset'";
|
||||||
};
|
};
|
||||||
script = ''
|
script = ''
|
||||||
set -u
|
set -euo pipefail
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
# Calculate memory to use for zram
|
|
||||||
totalmem=$(${pkgs.gnugrep}/bin/grep 'MemTotal: ' /proc/meminfo | ${pkgs.gawk}/bin/awk '{print $2}')
|
|
||||||
mem=$(((totalmem * ${toString cfg.memoryPercent} / 100 / ${toString cfg.numDevices}) * 1024))
|
|
||||||
|
|
||||||
echo $mem > /sys/class/block/${dev}/disksize
|
# Calculate memory to use for zram
|
||||||
|
mem=$(${pkgs.gawk}/bin/awk '/MemTotal: / {
|
||||||
|
print int($2*${toString cfg.memoryPercent}/100.0/${toString devicesCount}*1024)
|
||||||
|
}' /proc/meminfo)
|
||||||
|
|
||||||
|
${pkgs.utillinux}/sbin/zramctl --size $mem --algorithm ${cfg.algorithm} /dev/${dev}
|
||||||
${pkgs.utillinux}/sbin/mkswap /dev/${dev}
|
${pkgs.utillinux}/sbin/mkswap /dev/${dev}
|
||||||
'';
|
'';
|
||||||
restartIfChanged = false;
|
restartIfChanged = false;
|
||||||
@ -111,6 +157,9 @@ in
|
|||||||
in listToAttrs ((map createZramInitService devices) ++ [(nameValuePair "zram-reloader"
|
in listToAttrs ((map createZramInitService devices) ++ [(nameValuePair "zram-reloader"
|
||||||
{
|
{
|
||||||
description = "Reload zram kernel module when number of devices changes";
|
description = "Reload zram kernel module when number of devices changes";
|
||||||
|
wants = [ "systemd-udevd.service" ];
|
||||||
|
after = [ "systemd-udevd.service" ];
|
||||||
|
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
@ -118,7 +167,11 @@ in
|
|||||||
ExecStart = "${modprobe} zram";
|
ExecStart = "${modprobe} zram";
|
||||||
ExecStop = "${modprobe} -r zram";
|
ExecStop = "${modprobe} -r zram";
|
||||||
};
|
};
|
||||||
restartTriggers = [ cfg.numDevices ];
|
restartTriggers = [
|
||||||
|
cfg.numDevices
|
||||||
|
cfg.algorithm
|
||||||
|
cfg.memoryPercent
|
||||||
|
];
|
||||||
restartIfChanged = true;
|
restartIfChanged = true;
|
||||||
})]);
|
})]);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user