Skip to content

Commit

Permalink
Support writeback of incompressible/idle pages and writeback_limit
Browse files Browse the repository at this point in the history
  • Loading branch information
vaeth committed Aug 24, 2019
1 parent 3ed92b4 commit e8c4089
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 9 deletions.
5 changes: 5 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# ChangeLog for zram-init:

*zram-init-9.0:
Martin Väth <martin at mvath.de>:
- Support writeback of incompressible/idle pages and writeback_limit
- Finally suppress the annoying output of the logger path

*zram-init-8.2:
Edlund Scott <at sredlund>:
- Fix variable typos and shell style
Expand Down
14 changes: 14 additions & 0 deletions openrc/conf.d/zram-init
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ num_devices=2
# size0, size1, ... are the variables for the sizes (in MB)
# mlim0, mlim1, ... are the variables for the maximal uncompressed memory (MB)
# back0, back1, ... are the variables for the backup device
# icmp0, icmp1, ... are the flags (if nonempty) for writing incompressible
# pages to the backup device (requires setting back*)
# idle0, idle1, ... are the flags (in nonempty) for writing idle pages to the
# backup device (requires setting back*)
# wlim0, wlim1, ... set the writeback_limit for idle pages (implies idle*)
# maxs0, maxs1, ... are the variables for the maximal (parallel) streams
# algo0, algo1, ... are the variables for the compression algorithms
# flag0, flag1, ... are the variables for the flags
Expand Down Expand Up @@ -52,6 +57,9 @@ flag0= # The default "16383" is fine for us
size0=`LC_ALL=C free -m | awk '/^Mem:/{print int($2/2)}'`
mlim0= # no hard memory limit
back0= # no backup device
icmp0= # no incompressible page writing to backup device
idle0= # no idle page writing to backup device
wlim0= # no writeback_limit for idle page writing for backup device
notr0= # keep the default on linux-3.15 or newer
maxs0=1 # maximum number of parallel processes for this device
algo0=zstd # zstd (since linux-4.18), lz4 (since linux-3.15), or lzo.
Expand All @@ -69,6 +77,9 @@ flag1=ext4
size1=2048
mlim1= # no hard memory limit
back1= # no backup device
icmp1= # no incompressible page writing to backup device
idle1= # no idle page writing to backup device
wlim1= # no writeback_limit for idle page writing for backup device
opts1="strictatime,nosuid,nodev,noexec" # e.g. "relatime" or "noatime" are also reasonable choices
mode1=1777
owgr1= # No reason to change the default "root:root"
Expand All @@ -85,6 +96,9 @@ flag2=ext2
size2=1024
mlim2= # no hard memory limit
back2= # no backup device
icmp2= # no incompressible page writing to backup device
idle2= # no idle page writing to backup device
wlim2= # no writeback_limit for idle page writing for backup device
opts2=relatime # e.g. "noatime" or "strictatime" are also reasonable choices
mode2=1777
owgr2= # No reason to change the default "root:root"
Expand Down
8 changes: 6 additions & 2 deletions openrc/init.d/zram-init
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ depend() {

ZramInit() {
set -- ${1+"$@"} -D "$num_devices" \
${mlim:+-S "$mlim"} ${back:+-b "$back"} ${notr:+-T} \
${mlim:+-S "$mlim"} ${back:+-b "$back"} \
${icmp:+-I} ${idle:+-w} ${wlim:+-W "$wlim"} \
${maxs:+-s "$maxs"} ${algo:+-a "$algo"} \
${labl:+-L "$labl"} ${uuid:+-U "$uuid"}
${labl:+-L "$labl"} ${uuid:+-U "$uuid"} ${notr:+-T}
[ -z "${args:++}" ] || eval 'set -- "$@" '"$args"
if [ x"$fstype" = x'swap' ]
then einfo "Swap->zram$2"
Expand Down Expand Up @@ -50,6 +51,9 @@ ZramIgnore() {
size=\${size$1:-0}
mlim=\${mlim$1}
back=\${back$1}
icmp=\${icmp$1}
idle=\${idle$1}
wlim=\${wlim$1}
maxs=\${maxs$1-}
algo=\${algo$1-}
flag=\${flag$1-}
Expand Down
54 changes: 47 additions & 7 deletions sbin/zram-init
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Echo() {
printf '%s\n' "$*"
}

if command -v logger
if command -v logger >/dev/null 2>&1
then EchoLog() {
Echo "$*"
logger "$*"
Expand Down Expand Up @@ -52,10 +52,12 @@ IsNumeric() {
}

Usage() {
Echo "Usage: ${0##*/} [options] SIZE [DIR]
Echo "Usage: ${0##*/} [options] SIZE|write [DIR]
Prepare a zram device and use it as swap (resp. mount it under DIR).
SIZE is the maximal size in megabytes.
For umounting/freeing the zram device, use SIZE=0.
When using \"write\" (or anything else starting with \"w\") an idle writeback
is forced (only makes sense if previously initialized with -w or -W LIMIT).
If DIR is - then only a filesystem is created in /dev/zram\$DEV (or the device
is removed if SIZE is 0) but it is not mounted
(options -o -c -m -T take no effect in this case, of course).
Expand All @@ -71,6 +73,9 @@ An empty argument means the same as if the option is not specified.
-s NUM Use up to NUM parallel compression streams for the device
-S MAX Use maximally MAX megabytes of uncompressed memory for the device
-b DEV Use DEV as backing device
-I If combined with -b DEV, store incompressible pages to backing device
-w If combined with -b DEV, enable idle writeback to backing device
-W LIMIT As -w but additionally set writeback_limit to LIMIT * 4kB.
-a ALGO Set compression algorithm to ALGO (e.g. zstd, lz4, or lzo)
-c OWNER If specified, chown to OWNER (resp. OWNER:GROUP) after mounting.
If not specified, the default owner (root:root) is not changed.
Expand Down Expand Up @@ -123,13 +128,17 @@ tune2fs_opt=
zramctl_opt=
mem_limit=
backing_dev=
writeback=false
writeback_limit=
incompressible=false
OPTIND=1
while getopts 's:S:a:b:c:d:D:m:o:p:t:i:N:L:U:TlkK:M:2:Z:hH' opt
while getopts 's:S:a:b:Ic:d:D:m:o:p:t:i:N:L:U:wW:TlkK:M:2:Z:hH' opt
do case $opt in
s) streams=$OPTARG;;
S) mem_limit=$OPTARG;;
a) algo=$OPTARG;;
b) backing_dev=$OPTARG;;
I) incompressible=:;;
c) owgr=$OPTARG;;
d) dev=$OPTARG;;
D) num=$OPTARG;;
Expand All @@ -141,6 +150,9 @@ do case $opt in
N) inodes=$OPTARG;;
L) label=$OPTARG;;
U) uuid=$OPTARG;;
w) writeback=:;;
W) writeback=:
writeback_limit=$OPTARG;;
T) discard=false;;
l) zramctl=false;;
k) keep=:;;
Expand All @@ -163,7 +175,22 @@ fi
: "${dev:=0}" "${prio:=16383}" "${fstype:=ext4}"

IsNumeric "$dev" || Fatal "device $dev is not numeric"

devnode=/dev/zram$dev
zclass=/sys/class/zram-control
block=/sys/block/zram$dev

case ${1:-0} in
w*)
SysCtlN idle "$block/writeback" || \
Fatal "failed to idle writeback zram$dev"
exit;;
esac

IsNumeric "${1:-0}" || Fatal "size $1 is not numeric"
IsNumeric "${mem_limit:-0}" || Fatal "mem_limit $mem_limit is not numeric"
IsNumeric "${writeback_limit:-0}" || \
Fatal "writeback_limit $writeback_limit is not numeric"

umount=:
if [ ${1:-0} -ne 0 ]
Expand All @@ -187,9 +214,6 @@ then swap=false
fi
fi

devnode=/dev/zram$dev
zclass=/sys/class/zram-control

HotAdd() {
while :
do curradd=
Expand Down Expand Up @@ -229,7 +253,6 @@ then $umount && exit
keep=:
}
fi
block=/sys/block/zram$dev
if ! $zramctl || [ -n "$mem_limit" ] || [ -n "${backing_dev:++}" ]
then test -d "$block" || Fatal "cannot find $block"
fi
Expand Down Expand Up @@ -257,6 +280,7 @@ fi
$umount && exit $status
test -b "$devnode" || HotAdd


if $zramctl && [ -z "${backing_dev:++}" ]
then eval "set -- a $zramctl_opt"
shift
Expand All @@ -271,6 +295,22 @@ else [ -z "$streams" ] || SysCtl "$streams" "$block/max_comp_streams" || \
[ -z "${backing_dev:++}" ] || \
SysCtlN "$backing_dev" "$block/backing_dev" || \
Warning "failed to set zram$dev backing_dev"
! $incompressible || SysCtlN huge "$block/write" || \
Warning "failed to set zram$dev incompressible writeback"
! $writeback || InitWriteback() {
SysCtlN all "$block/idle" || {
Warning "failed to set zram$dev idle writeback"
return
}
[ -n "${writeback_limit:++}" ] || return 0
SysctlN 1 "$block/writeback_limit_enable" || {
Warning "failed to enable writeback_limit for zram$dev"
return
}
SysctlN "$writeback_limit" "$block/writeback_limit" || \
Warning "failed to set writeback_limit $writeback_limit for zram$dev"
}
! $writeback || InitWriteback
SysCtl "$size" "$block/disksize" || Fatal "cannot set zram$dev size"
fi
[ -z "$mem_limit" ] || SysCtl "$mem_limit" "$block/mem_limit" || \
Expand Down
3 changes: 3 additions & 0 deletions zsh/_zram-init
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ _arguments -s -S -A '-*' : \
'(2 -t -c -m -o)-p+[use specified priority for swap]:priority for swap:(0 1 16383 -)' \
'(-p)-t+[use specified filesystem type]:filesystem type:(ext2 ext4 btrfs)' \
'-b+[use specifed device as backing device]:device:_files -g "*(-%b,-/)"' \
'-I[enable incompressible writeback on backing device]' \
'-w[enable idle writeback on backing device]' \
'-W+[use specifed number (times 4kB) as writeback_limit]:4kB writeback_limit:(50 100 300 512 2048 4096 6144 8192 16384)' \
'-D+[use specifed number of devices for modprobe]:number of devices:(1)' \
'-c+[chown to specified owner]:owner\:group:(nobody\:nogroup)' \
'-m+[chmod to specified mode]:mode:(1777 755 770)' \
Expand Down

0 comments on commit e8c4089

Please sign in to comment.