2019年12月31日 星期二

zram memory compress in embedded linux 5/6

1. Kconfing
gedit ~/linux-6.6.x/drivers/block/zram/Kconfig
choice
    prompt "Default zram compressor"
    ###default ZRAM_DEF_COMP_LZORLE
    default ZRAM_DEF_COMP_ZSTD
    depends on ZRAM

#config ZRAM_DEF_COMP_LZORLE
#    bool "lzo-rle"
#    depends on CRYPTO_LZO

config ZRAM_DEF_COMP_ZSTD
    bool "zstd"
    depends on CRYPTO_ZSTD

#config ZRAM_DEF_COMP_LZ4
#    bool "lz4"
#    depends on CRYPTO_LZ4

#config ZRAM_DEF_COMP_LZO
#    bool "lzo"
#    depends on CRYPTO_LZO

#config ZRAM_DEF_COMP_LZ4HC
#    bool "lz4hc"
#    depends on CRYPTO_LZ4HC

#config ZRAM_DEF_COMP_842
#    bool "842"
#    depends on CRYPTO_842
endchoice

2. defconfig use zram only no zswap
CONFIG_X86_MSR=y                                    # cpupower need only in x64
CONFIG_SWAP=y                                           # System Switching Memory
CONFIG_ZSWAP=n                                        # Pre-I/O compression
CONFIG_ZPOOL=n                                        # zswap using
CONFIG_ZBUD=n                                          # zswap using
CONFIG_Z3FOLD=n                                      # zswap using
CONFIG_ZRAM=m
CONFIG_ZRAM_DEF_COMP_ZSTD=y
CONFIG_ZRAM_WRITEBACK=y                    #Allow writeback to disk
CONFIG_ZRAM_MEMORY_TRACKING=n  # Track memory usage
CONFIG_ZSMALLOC=y                                # ZRAM Memory Allocator (Important!)
CONFIG_ZSMALLOC_CHAIN_SIZE=8        # Optional: chain size (Linux v6 required)
CONFIG_CRYPTO_ZSTD=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y

3. cpupower tool
###setting CROSS CFLAGS LDFLAGS, cpupower auto find libpci.so
gedit ~/linux-5.10.107/tools/power/cpupower/Makefile
CROSS = $(CROSS_COMPILE)
CC = $(CROSS)gcc
LD = $(CROSS)gcc
AR = $(CROSS)ar
STRIP = $(CROSS)strip
RANLIB = $(CROSS)ranlib
HOSTCC = gcc
MKDIR = mkdir
CFLAGS=$(STAGING_CFLAGS)
LDFLAGS=$(STAGING_LDFLAGS) -lz -ludev -lcap

gedit ~/build/Makefile
###after linux and third party lib installed run kernel-install-cpupower
kernel-install-cpupower:
    @echo "install cpupower..."
    @[ -d $(KERNEL_BUILD_DIR)/tools/power/cpupower ] || install -m 755 -d $(KERNEL_BUILD_DIR)/tools/power/cpupower
    @[ -d $(DESTDIR)/usr/lib ] || install -m 755 -d $(DESTDIR)/usr/lib
    @[ -d $(DESTDIR)/usr/bin ] || install -m 755 -d $(DESTDIR)/usr/bin
    @$(MAKE) -C $(KERNEL_SRC_DIR)/tools/power/cpupower O=$(KERNEL_BUILD_DIR)/tools/power/cpupower
    @$(CMD_CP) -f  $(KERNEL_BUILD_DIR)/tools/power/cpupower/libcpupower.* $(DESTDIR)/usr/lib
    @$(CMD_CP) -f  $(KERNEL_BUILD_DIR)/tools/power/cpupower/cpupower $(DESTDIR)/usr/bin

4. inittab
gedit ~/build/skeleton/etc/inittab
###after /volume1 mount run zraminit.sh
# Initialize the ZRAM equipment(this should be done before the main services start)
::sysinit:/etc/script/zraminit.sh
::once:/etc/script/zramwbwatch.sh

5. zraminit.sh
#!/bin/sh -x
#using [-x] for debugging
echo "ZRAM Starting..."

# Cpu strategy
cpupower frequency-set -g performance

for epp in /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference; do
    if [ -f "$epp" ]; then
        echo "Setting $epp to performance"
        echo "performance" > "$epp"
    fi
done

# Load zram module
modprobe zram num_devices=1

remain=10
while [ ! -b /dev/zram0 ] && [ "$remain" -gt 0 ]; do
    echo "Waiting for /dev/zram0 to be ready... remaining attempts: $remain"
    sleep 0.1
    remain=$((remain - 1))
done

# avoid reset "device busy" errors then reset
if [ "$(awk '$1=="/dev/zram0"{print 1}' /proc/swaps)" ]; then
    echo "zram found, now closing..."
    swapoff /dev/zram0
fi

if [ -w /sys/block/zram0/reset ]; then
    echo 1 > /sys/block/zram0/reset
fi

# Set the compression algorithm
echo "zstd" > /sys/block/zram0/comp_algorithm

# Node algorithm_params not create
#if [ -w /sys/block/zram0/algorithm_params ]; then
#    echo "algo=zstd level=4" > /sys/block/zram0/algorithm_params
#fi

# zram_drv.c lock, per-cpu streams use all core after linux 4.7
#CPU_NUM=$(($(grep -c processor /proc/cpuinfo)/2))
#if [ -w /sys/block/zram0/max_comp_streams ]; then
#    echo $CPU_NUM > /sys/block/zram0/max_comp_streams
#fi

#ZRAM writeback 4GB
if [ ! -f "/volume1/zram_back" ]; then
    echo "Creating backing file..."
    dd if=/dev/zero of="/volume1/zram_back" bs=1M count=8192
fi

#Clean up all old loop devices bound with zram_back
for old_looping in $(losetup -a | grep "/volume1/zram_back" | cut -d ':' -f 1); do
    echo "Unbinding old loop: $old_looping"
    losetup -d "$old_looping"
done

LOOP_DEV=$(losetup -f)
if [ -n "$LOOP_DEV" ]; then
    echo "Using $LOOP_DEV as backing..."
    if losetup "$LOOP_DEV" "/volume1/zram_back"; then
        if ! echo "$LOOP_DEV" > /sys/block/zram0/backing_dev; then
            echo "Error: failed to bind $LOOP_DEV to zram0"
            losetup -d "$LOOP_DEV"
        fi
    else
        echo "Error: could not associate $LOOP_DEV with /volume1/zram_back"
        losetup -d "$LOOP_DEV"
    fi
else    
    echo "Error: no free loop devices found!"
fi

# Use half physical memory
memkb=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
zsize=$((memkb * 1024 / 2))
echo $zsize > /sys/block/zram0/disksize

# Format as swap
mkswap /dev/zram0
swapon /dev/zram0 -p 100 # Use appropriate priority
# setting it to 100 allows the system to more actively utilize compressed space
sysctl -w vm.swappiness=100
# read ahead 2^n page, n=0 page=1
sysctl -w vm.page-cluster=0

6. zramwbwatch.sh
#!/bin/sh -x
#using [-x] for debugging

while true; do

    memused=$(free | grep Mem | awk '{print int(($2-$7)/$2*100)}')
    if [ "$memused" -ge 85 ]; then
        echo "[$(date)] memory usage ${memused}% >= 85%, execute ZRAM writeback..."
        echo all > /sys/block/zram0/idle
        echo huge > /sys/block/zram0/writeback
        echo idle > /sys/block/zram0/writeback
    fi

    sleep 60

done

7. monitor zram working
watch -n1 "cat /proc/swaps"

###memory usage%
watch -n1 "free | grep Mem | awk '{print int((\$2-\$7)/\$2*100)}'"

watch -n1 "cat /sys/block/zram0/mm_stat "
orig_data_size | compr_data_size | mem_used_max | mem_limit | mem_used_total same_pages | pages_compacted | huge_pages

watch -n1 "cat /sys/block/zram0/bd_stat"
pages_on_bd | bd_reads bd_| writes

###give memory stress
(DATA=$(dd if=/dev/urandom bs=1M count=50); sleep 120; unset DATA) &

refer to:
For writeback feature, user should set up backing device before the zram working.
https://lore.kernel.org/all/1498459987-24562-10-git-send-email-minchan@kernel.org/T/#u

沒有留言:

張貼留言