Projects and resources (En) > Tips and tricks

Install ZRAM in Debian

(1/1)

djohnston:
Zram is a kernel module which has been available in the vanilla Linux kernels since version 2.6.37. Nitin Gupta is the author/developer. The project started as compcache and the module name was later changed to zram.

http://code.google.com/p/compcache


--- Citer ---This project creates RAM based block device (named zram) which acts as swap disk. Pages swapped to this disk are compressed and stored in memory itself.

Compressing pages and keeping them in RAM virtually increases its capacity. This allows more applications to fit in given amount of memory. (...)
--- Fin de citation ---

When the kernel module is enabled, it can be used to create a block device that acts as a swap device.

The block device occupies a portion of physical RAM. When memory pressure is enough that the swap device is called, the memory pages are written to the zram block device instead of a standard disk block device. Because I/O reads and writes to physical RAM are much faster than to a disk drive, zram responds much more quickly than a swap file or partition. In addition, paged memory is compressed when written to the zram block device and decompressed when the pages are freed. This has the effect of increasing available memory, even when a conventional swap file or partition has been created. The memory pages will be written to the zram device before anything is written to the conventional swap space.

Because zram is a kernel module, it has either been enabled in the kernel you are running, or not. To check whether zram is enabled, enter the following in a terminal as a normal user:


--- Code: ---zgrep ZRAM /proc/config.gz
--- Fin du code ---

You will see the following if it is enabled:

CONFIG_ZRAM=m
# CONFIG_ZRAM_DEBUG is not set

The DEBUG option may or may not be set. If you see the CONFIG_ZRAM=m string, your kernel has the zram module enabled. You may see CONFIG_ZRAM=m. '=y' would mean it is hard coded in the kernel, whereas '=m' means it is a kernel module that can be optionally loaded or unloaded. Stock Ubuntu kernels have the module enabled. Stock Debian kernels do not. To get the functionality in Debian, the kernel must be recompiled with the module enabled and an initrd image created. Or, the kernel can be replaced with one with the module already enabled. The kernel I use is the liquorix kernel, which has the zram module already enabled. It is only available from the liquorix repository. To add the repository to any Debian based distribution, do the following as user root in a terminal:


--- Code: ---touch /etc/apt/sources.list.d/liquorix.list
--- Fin du code ---


--- Code: ---echo deb http://liquorix.net/debian sid main > /etc/apt/sources.list.d/liquorix.list
--- Fin du code ---


--- Code: ---apt-get update
--- Fin du code ---

You will likely get an error similar to the following:

W: GPG error: http://liquorix.net sid InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 3EFF4F272FB2CD80

That's because the liquorix keyring has not been installed yet. Do so as user root with the following:


--- Code: ---apt-get install '^liquorix-([^-]+-)?keyring.?'
--- Fin du code ---

To install the kernel and headers, do as user root in a terminal:


--- Code: ---apt-get install linux-image-liquorix-*
--- Fin du code ---

Among the messages, you should see:

The following NEW packages will be installed:
  linux-headers-3.7.0-5.dmz.2-liquorix-686 linux-headers-liquorix-686
  linux-image-3.7.0-5.dmz.2-liquorix-686 linux-image-liquorix-686

The linux-headers and linux-image versions may be different, but you should see two linux-headers packages and two linux-headers packages listed. If you only see two linux-image packages listed, apt does not have the recommended packages option set. Install the two kernel packages. Then do as user root:


--- Code: ---apt-get install linux-headers-liquorix-*
--- Fin du code ---

That will install the two missing linux-headers packages. On the next reboot, check the boot screen to see that the new kernel is selected by default. If not, select it manually. After booting, you can double-check the kernel version that is running by entering the following in a terminal as a normal user:


--- Code: ---uname -r
--- Fin du code ---

After booting, you may remove your old kernel if you wish. Now that a zram enabled kernel is installed and running, you may install the zram configuration files. They must be installed before zram can be started. Debian offers no deb package for this. You will have to create the executable and configuration files manually. There are only three files, and the contents of two of them are the same. As root, copy and paste the following into your favorite text editor:



--- Code: ---#!/bin/bash
### BEGIN INIT INFO
# Provides: zram
# Required-Start: $local_fs
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Increased Performance In Linux With zRam (Virtual Swap Compressed in RAM)
# Description: Adapted from systemd scripts at https://github.com/mystilleef/FedoraZram
# Included as part of antix-goodies package by anticapitalista <antiX@operamail.com>
# This script was written by tradetaxfree and is found at http://crunchbanglinux.org/forums/topic/15344/zram-a-good-idea/
# Extraneous commented (disabled) commands removed by djohnston at http://linuxvillage.net/
# Copy this script (as root) from /usr/local/bin to /etc/init.d and then #update-rc.d zram defaults
# After booting verify the module is loaded with: lsmod | grep zram
### END INIT INFO

start() {
    # get the number of CPUs
    num_cpus=$(grep -c processor /proc/cpuinfo)
    # if something goes wrong, assume we have 1
    [ "$num_cpus" != 0 ] || num_cpus=1

    # set decremented number of CPUs
    last_cpu=$((num_cpus - 1))
   
       #default Factor % = 90 change this value here or create /etc/default/zram[/b][/color]
       FACTOR=90
       #& put the above single line in /etc/default/zram with the value you want
[ -f /etc/default/zram ] && source /etc/default/zram || true
factor=$FACTOR # percentage

    # get the amount of memory in the machine
     memtotal=$(grep MemTotal /proc/meminfo | sed 's/[^0-9]\+//g')
     mem_by_cpu=$(($memtotal/$num_cpus*$factor/100*1024))

    # load dependency modules
    modprobe zram num_devices=$num_cpus
   
    if [ $? -gt 0 ]; then
      echo -e "Your Kernel needs to be compiled with ZRAM support:" \
      "\n\nDevice Drivers --> Staging Drivers --> Compressed RAM block device support (M)" \
      "\nDevice Drivers --> Staging Drivers --> Dynamic compression of swap pages and clean pagecache pages (*)" \
      "\n\nThe Liquorix Kernel (http://liquorix.net) has ZRAM support built in."
      exit 1
    fi
    echo "zram devices probed successfully"
   
    # initialize the devices
    for i in $(seq 0 $last_cpu); do
    echo $mem_by_cpu > /sys/block/zram$i/disksize
    # Creating swap filesystems
    mkswap /dev/zram$i
    # Switch the swaps on
    swapon -p 100 /dev/zram$i
    done
}

stop() {
    # get the number of CPUs
    num_cpus=$(grep -c processor /proc/cpuinfo)

    # set decremented number of CPUs
    last_cpu=$((num_cpus - 1))

    # Switching off swap
    for i in $(seq 0 $last_cpu); do
    if [ "$(grep /dev/zram$i /proc/swaps)" != "" ]; then
    swapoff /dev/zram$i
    sleep 1
    fi
    done

    sleep 1
    rmmod zram
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 3
        start
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        RETVAL=1
esac
exit $RETVAL
--- Fin du code ---


Save the file as /usr/local/bin/zram. Set the file attributes as user root from a terminal:


--- Code: ---chmod 755 /usr/local/bin/zram
--- Fin du code ---


--- Code: ---chown root:root /usr/local/bin/zram
--- Fin du code ---

Then copy the file to its second location:


--- Code: ---cp /usr/local/bin/zram /etc/init.d/zram
--- Fin du code ---

Both of the newly created files are bash scripts and must be executable to function correctly. Did you notice this line?


--- Citer ---FACTOR=90
--- Fin de citation ---

The FACTOR is equivalent to the percentage of RAM to be used as a zram device. The default is 90%. It should be changed. You do not need to edit the value in both bash scripts. The percentage value can be changed by creating a configuration file. This file is so small you may as well do it from a terminal as root.


--- Code: ---touch /etc/default/zram
--- Fin du code ---


--- Code: ---echo FACTOR=25 > /etc/default/zram
--- Fin du code ---


--- Code: ---chmod 644 /etc/default/zram
--- Fin du code ---

In the example above, the percentage of RAM to be used as a zram block device is 25%. That is the recommended value. The value specified in /etc/default/zram will override the value in the two executable bash scripts. Now that the configuration files have been created, you must enable zram by doing as user root:


--- Code: ---update-rc.d zram defaults
--- Fin du code ---

After that has been done, zram will be automatically enabled at every boot. To be sure everything has been set up correctly, you can do as root:


--- Code: ---/etc/init.d/zram start
--- Fin du code ---


--- Code: ---cat /proc/swaps
--- Fin du code ---

You should then see zram listed as a swap device. If it is not showing, you have missed something in the steps. Retrace your steps.

Zram is enabled by default in the AndroidOS. As of Slax version 7, it has been enabled by default. I'm sure there are other examples.

There are at least two methods for manually enabling zram. Another method involves creating the zram block device, configuring its size, and adding it as a swap device entry to /etc/fstab. The disadvantage to that method is that the size of the zram block device cannot be dynamically resiZed. The advantages to the method I have described is that a percentage of memory can be used, rather than a user-defined fixed size, and that a zram device will be created for each CPU core, minus one. In other words, if you have a CPU with four cores, three zram devices will be crated. If you have two CPUs, each with four cores, seven zram devices will be created. This has the advantage of distributing the CPU load in handling the zram block device(s).

melodie:
Hi djohnston,

At the moment in Debian Wheezy, there are new things. There is no /proc/config.gz file anymore, and zram is default enabled in the current kernel, the 3.2.0-4-686-pae is the one installed.

I am having a look here:
http://crunchbang.org/forums/viewtopic.php?id=15344&p=1

Maybe would you want to compare the script you used and the one from the crunchbang forum member, and see what can be reviewed in the method you presented here last February?

PS: this could be useful later:
http://antix.freeforums.org/post25726.html#p25726

The "zram-b" one adopted for antiX:
http://pastebin.com/ZEKyMEx0


--- Code: ---#!/bin/bash
### BEGIN INIT INFO
# Provides: zram
# Required-Start: $local_fs
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Increased Performance In Linux With zRam (Virtual Swap Compressed in RAM)
# Description: Adapted from systemd scripts at [url]https://github.com/mystilleef/FedoraZram[/url]
# Included as part of antix-goodies package by anticapitalista <antiX@operamail.com>
# This script was written by tradetaxfree and is found at http://crunchbanglinux.org/forums/topic/15344/zram-a-good-idea/
# Copy this script (as root) from /usr/local/bin to /etc/init.d and then #update-rc.d zram defaults
# After booting verify the module is loaded with: lsmod | grep zram
### END INIT INFO

start() {
    # get the number of CPUs
    num_cpus=$(grep -c processor /proc/cpuinfo)
    # if something goes wrong, assume we have 1
    [ "$num_cpus" != 0 ] || num_cpus=1

    # set decremented number of CPUs
    last_cpu=$((num_cpus - 1))
   
    #default Factor % = 90 change this value here or create /etc/default/zram
    FACTOR=90
    #& put the above single line in /etc/default/zram with the value you want
[ -f /etc/default/zram ] && source /etc/default/zram || true
factor=$FACTOR # percentage

    # get the amount of memory in the machine
#    memtotal=$(grep MemTotal /proc/meminfo | awk ' { print $2 } ')
     memtotal=$(grep MemTotal /proc/meminfo | sed 's/[^0-9]\+//g')
   mem_by_cpu=$(($memtotal/$num_cpus*$factor/100*1024))

    # load dependency modules
    # kernels 3.4 onwards
   
    modprobe zram num_devices=$num_cpus
   
    if [ $? -gt 0 ]; then
  # kernels 3.1 - 3.3
      #modprobe zram zram_num_devices=$num_cpus       
    #else
      echo -e "Your Kernel needs to be compiled with ZRAM support:" \
      "\n\nDevice Drivers --> Staging Drivers --> Compressed RAM block device support (M)" \
      "\nDevice Drivers --> Staging Drivers --> Dynamic compression of swap pages and clean pagecache pages (*)" \
      "\n\nThe Liquorix Kernel (http://liquorix.net) has ZRAM support built in."
      exit 1
    fi
    echo "zram devices probed successfully"
   
    # initialize the devices
    for i in $(seq 0 $last_cpu); do
    echo $mem_by_cpu > /sys/block/zram$i/disksize
    # Creating swap filesystems
    mkswap /dev/zram$i
    # Switch the swaps on
    swapon -p 100 /dev/zram$i
    done
}

stop() {
    # get the number of CPUs
    num_cpus=$(grep -c processor /proc/cpuinfo)

    # set decremented number of CPUs
    last_cpu=$((num_cpus - 1))

    # Switching off swap
    for i in $(seq 0 $last_cpu); do
    if [ "$(grep /dev/zram$i /proc/swaps)" != "" ]; then
    swapoff /dev/zram$i
    sleep 1
    fi
    done

    sleep 1
    rmmod zram
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 3
        start
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        RETVAL=1
esac
exit $RETVAL
--- Fin du code ---

I haven't finished testing and comparing the results of the actual zram script from tradetaxfree and the one for antiX modified last year. Both have glitches which are not the same once installed to Debian, and at same time both seem to work.

Not to be forgottent:

--- Code: ---/etc/default/zram
FACTOR=25
--- Fin du code ---


melodie:
The conclusion:

The script reviewed by mimas and captnfab (from the debian-facile.org community, among else) last year work when started during the session, but after reboot zram was not activated, and in the dmesg log I can read:

--- Citer ---zram: Unknown parameter `num_devices'
--- Fin de citation ---

A research on the web led me here:
https://aur.archlinux.org/packages/zramswap/?comments=all

where I learned how to detect which parameter was expected, with this command line:

--- Citer --- Comment by dront78

2012-08-31 09:59

you can use

--- Code: ---modinfo zram | grep -E -o '(num_devices|zram_num_devices)'
--- Fin du code ---
to detect parameter supported by a kernel and use /dev/null instead of /tmp/zramswap-$$.log

--- Fin de citation ---

which I used, to find as I was suspecting, that the right parameter for this kernel version is is zram_num_devices.

Therefore I commented the wrong line and added one more after:

--- Code: ---    # load dependency modules
    # kernels 3.4 onwards
   
#    modprobe zram num_devices=$num_cpus
      modprobe zram zram_num_devices=$num_cpus
   
    if [ $? -gt 0 ]; then
  # kernels 3.1 - 3.3
--- Fin du code ---

Conclusion: after a full reboot, with the above change, it works perfect and there is no more error message. Instead, after the classic warning related to the staging directory the message from dmesg says:

--- Citer ---zram: Creating 2 devices ...
--- Fin de citation ---

Nice isn't it ?


However the same line (modprobe zram zram_num_devices=$num_cpus) is also after "if [ $? -gt 0 ]; then" and before the "echo" part, and had been commented last year. Now for this reason someone keen with shell scripts would be welcome to clean up this script (which one was supposed to go before or after and why? I have no idea) and also add mimas and captnfab as contributors besides tradetaxfree, for they have been the ones who allowed it to work in antiX last year and therefore to almost work in the actual Debian !

melodie:
Here is a set of related files:
http://meets.free.fr/Downloads/Debian/zramconfig

The init script
http://meets.free.fr/Downloads/Debian/zramconfig/zram/etc/init.d/zram

now contains this line for the modprobe action:

--- Code: ---modprobe zram $(modinfo zram | grep -E -o '(num_devices|zram_num_devices)')=$num_cpus
--- Fin du code ---

The idea is from captnfab who therefore solved the "num_devices/zram_num_devices" problem: one kernel uses one parameter while some more recent kernels use the other. With this setup it should work for the actual kernel and many kernels to come.


Edit:
In case the system starts swapping to disk before the whole ram is used, parameters can be added to a /etc/sysctl.d/local.conf file such as this one: 50-local.conf


--- Code: ---## Configure swappiness
# Uncomment the next line if we are running a laptop
# vm.laptop_mode = 1
vm.swappiness=0
vm.vfs_cache_pressure=50

--- Fin du code ---


Navigation

[0] Index des messages

Utiliser la version classique