zram-config doesn't start if zram is built-in, not module

Bug #1270913 reported by Nazar Mokrynskyi
24
This bug affects 5 people
Affects Status Importance Assigned to Milestone
zram-config (Ubuntu)
Confirmed
Medium
Unassigned

Bug Description

zram-config works only if zram is compiled as module, if built-in then

modinfo zram | grep -q ' zram_num_devices:' 2>/dev/null;

and

modinfo zram | grep -q ' num_devices:' 2>/dev/null;

from file /etc/init/zram-config.conf returns false.

Looks like check should be another, proper check for zram availability.

Changed in zram-config (Ubuntu):
importance: Undecided → Medium
Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in zram-config (Ubuntu):
status: New → Confirmed
Revision history for this message
Lenin (gagarin) wrote :

Maybe one of the zram-config maintainers want to update

end-zram-swapping
#!/bin/sh

if DEVICES=$(grep zram /proc/swaps | awk '{print $1}'); then
  for i in $DEVICES; do
    swapoff $i
  done
fi
lsmod |grep zram >/dev/null && rmmod zram

init-zram-swapping
#!/bin/sh

# load dependency modules
if grep ZRAM=m /boot/config-$(uname -r)
  NRDEVICES=$(grep -c ^processor /proc/cpuinfo | sed 's/^0$/1/')
  if modinfo zram | grep -q ' zram_num_devices:' 2>/dev/null; then
    MODPROBE_ARGS="zram_num_devices=${NRDEVICES}"
  elif modinfo zram | grep -q ' num_devices:' 2>/dev/null; then
    MODPROBE_ARGS="num_devices=${NRDEVICES}"
  else
    exit 1
  fi
  modprobe zram $MODPROBE_ARGS
fi

# Calculate memory to use for zram (1/2 of ram)
totalmem=`LC_ALL=C free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/ *.*//'`
mem=$(((totalmem / 2 / ${NRDEVICES}) * 1024))

# initialize the devices
for i in $(seq ${NRDEVICES}); do
  DEVNUMBER=$((i - 1))
  echo $mem > /sys/block/zram${DEVNUMBER}/disksize
  mkswap /dev/zram${DEVNUMBER}
  swapon -p 5 /dev/zram${DEVNUMBER}
done

Revision history for this message
stuart naylor (stuartiannaylor68) wrote :

https://www.kernel.org/doc/Documentation/blockdev/zram.txt

"num_devices parameter is optional and tells zram how many devices should be
pre-created. Default: 1"

The whole first procedure is a question to why and completely fails to check previous devices or modprobe zram services:-
*******************************************************************
# load dependency modules
if grep ZRAM=m /boot/config-$(uname -r)
  NRDEVICES=$(grep -c ^processor /proc/cpuinfo | sed 's/^0$/1/')
  if modinfo zram | grep -q ' zram_num_devices:' 2>/dev/null; then
    MODPROBE_ARGS="zram_num_devices=${NRDEVICES}"
  elif modinfo zram | grep -q ' num_devices:' 2>/dev/null; then
    MODPROBE_ARGS="num_devices=${NRDEVICES}"
  else
    exit 1
  fi
  modprobe zram $MODPROBE_ARGS
fi
*****************************************************************
zram can be easily checked to see if it has a sys class

        ZRAM_SYS_DIR='/sys/class/zram-control'
        if [ ! -d "${ZRAM_SYS_DIR}" ]; then

if not then modprobe zram will create it.
So after a modprobe zram all you have to do is create first device /dev/zram0
As cat /sys/class/zram-control/hot_add will always contain the next device number and will already contain '1'

After that

      RAM_DEV=$(cat /sys/class/zram-control/hot_add)
      echo ${COMP_ALG_SWAP} > /sys/block/zram${RAM_DEV}/comp_algorithm
      echo ${mem} > /sys/block/zram${RAM_DEV}/disksize
      mkswap /dev/zram${RAM_DEV}
      swapon -p ${SWAP_PRI} /dev/zram${RAM_DEV}
is all that is needed as cat /sys/class/zram-control/hot_add is incremented on each addition

But then we have the questions of if a single device is automatically allocated streams for all cores why add a block device for each core?

Also zram can use all crypto listed in proc/crypto but its hard coded.
Same for swap priority & size setting.

There is little correlation in the methods used in zram-config & https://www.kernel.org/doc/Documentation/blockdev/zram.txt and maybe someone should ask why?

Revision history for this message
stuart naylor (stuartiannaylor68) wrote :

zram_config because it makes absolutely no check and overwrites any previous zram devices due to hard coding.

I have been trying to do something simple as use log2ram with a compressed zram drive.
Came to the conclusion that because of zero checks via zram_config its impossible to have both in operation unless provide zram control in log2ram.

After doing that and some reading of https://www.kernel.org/doc/Documentation/blockdev/zram.txt I am completely bemused to what, why and how zram_config operates and prob someone needs to ask https://www.linkedin.com/in/nitingupta910 the kernel author of zram some advise.

You can have a look at what I have done in https://github.com/StuartIanNaylor/log2ram/blob/master/log2ram but wouldn't touch zram_config with a bargepole.
Also asked these questions in https://answers.launchpad.net/ubuntu/+source/zram-config/+question/678905

As there seems to be little correlation with zram_config & https://www.kernel.org/doc/Documentation/blockdev/zram.txt !!?

Revision history for this message
stuart naylor (stuartiannaylor68) wrote :
Download full text (3.4 KiB)

PS just had a thought and this is from chromium OS

https://chromium.googlesource.com/chromiumos/platform/init/+/factory-3536.B/swap.conf

# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
description "Setup compressed memory swap"
author "<email address hidden>"
# Set margin for low-memory notifier (for tab discarder)
# Configure and start swap if SWAP_ENABLE_FILE exists.
# SWAP_ENABLE_FILE may optionally contain the uncompressed swap size (in Mb).
# Otherwise it is set to 1.5 times total RAM.
#
# To start swap, create file /home/chronos/.swap_enabled and run "start swap"
# or reboot. To stop swap, remove the file and reboot.
start on starting system-services
script
  SWAP_ENABLE_FILE=/home/chronos/.swap_enabled
  HIST_MIN=100
  HIST_MAX=10000
  HIST_BUCKETS=50
  HIST_ARGS="$HIST_MIN $HIST_MAX $HIST_BUCKETS"
  # Extract second field of MemTotal entry in /proc/meminfo.
  # NOTE: this could be done with "read", "case", and a function
  # that sets ram=$2, for a savings of about 3ms on an Alex.
  ram=$(awk '/MemTotal/ { print $2; }' < /proc/meminfo)
  [ "$ram" = "" ] && logger -t "$UPSTART_JOB" "could not get MemTotal"
  # compute fraction of total RAM used for low-mem margin. The fraction is
  # given in bips. A "bip" or "basis point" is 1/100 of 1%. This unit is
  # typically used in finance and in low-memory margin calculations.
  MARGIN_BIPS=520
  margin=$(($ram / 1000 * $MARGIN_BIPS / 10000)) # MB
  # set the margin
  echo $margin > /sys/kernel/mm/chromeos-low_mem/margin
  logger -t "$UPSTART_JOB" "setting low-mem margin to $margin MB"
  if [ ! -f $SWAP_ENABLE_FILE ]; then
    metrics_client Platform.CompressedSwapSize 0 $HIST_ARGS
    exit 0
  fi
  # Load zram module. Ignore failure (it could be compiled in the kernel).
  modprobe zram || logger -t "$UPSTART_JOB" "modprobe zram failed (compiled?)"
  # Allocate zram (compressed ram disk) for swap.
  # Default for uncompressed size is 1.5 of total memory.
  # Override with content of .swap_enabled (in Mb).
  # Calculations are in Kb to avoid 32 bit overflow.
  # For security, only read first few bytes of SWAP_ENABLE_FILE.
  REQUESTED_SIZE_MB="$(head -c 4 $SWAP_ENABLE_FILE)"
  if [ -z "$REQUESTED_SIZE_MB" ]; then
    ZRAM_SIZE_KB=$(awk '/MemTotal/ { print $2 * 3 / 2 }' /proc/meminfo)
  elif [ "$REQUESTED_SIZE_MB" != 500 -a \
         "$REQUESTED_SIZE_MB" != 1000 -a \
         "$REQUESTED_SIZE_MB" != 2000 -a \
         "$REQUESTED_SIZE_MB" != 3000 -a \
         "$REQUESTED_SIZE_MB" != 4000 -a \
         "$REQUESTED_SIZE_MB" != 4500 -a \
         "$REQUESTED_SIZE_MB" != 6000 ]; then
    logger -t "$UPSTART_JOB" "invalid value $REQUESTED_SIZE_MB for swap"
    metrics_client Platform.CompressedSwapSize 0 $HIST_ARGS
    exit 1
  else
    ZRAM_SIZE_KB=$(($REQUESTED_SIZE_MB * 1024))
  fi
  logger -t "$UPSTART_JOB" "setting zram size to $ZRAM_SIZE_KB Kb"
  # Approximate the kilobyte to byte conversion to avoid issues
  # with 32-bit signed integer overflow.
  echo ${ZRAM_SIZE_KB}000 >/sys/block/zram0/disksize ||
      logger -t "$UPSTART_JOB" "failed to set ...

Read more...

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.