Skip to content

Commit

Permalink
v2 (20191221)
Browse files Browse the repository at this point in the history
new: Set ZRAM default size based on physical memory size
new: Set minfree based on physical memory size
new: Optional ZRAM level of 2.5GB
improve: Do not change comp_algorithm to LZ4, use only default values
improve: Removed memcg that caused long freezes to reduce excessive page cache drops
improve: Keep page cache more aggressive under high memory pressure
fix: 2 zram devices are not turned off on LG devices
fix: Setting zram size to 0 shows 1.5
fix: swapon swapoff compatibility issues prevent enabling ZRAM
Signed-off-by: Matt Yang <yccy@outlook.com>
  • Loading branch information
yc9559 committed Dec 21, 2019
1 parent 47ed50e commit 632be15
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 162 deletions.
39 changes: 28 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
# Memory management optimaization for Qualcomm platform

## Feature

English version:
- Remove QTI ActivityManager CUR_MAX_EMPTY_PROCESSES limit
- lowmemorykiller tend to keep tasks which adj < 950
- lowmemorykiller tend to remove tasks which adj >= 950
- Pure memory management optimization module, not containing other placebo and supporting mainstream Snapdragon platforms
- Solve the problem that the background can't hang even if the free memory is large, by removing QTI ActivityManager CUR_MAX_EMPTY_PROCESSES
- Disable automatic kill when vmpressure >= 90
- Higher watermark_mid reduces the possibility of direct memory allocation
- Avoid swapping latency intensive processes, such as `system_server`, `systemui` and `launcher`
- Reduce jitters under high memory pressure, lowmemorykiller tends to kill the process of adj> = 950, so that the file page cache is kept at a high level
- Reduce stucks under high memory pressure, reduce the probability of direct memory allocation via higher watermark_mid
- Avoid swapping memory pages which are hard to compress to ZRAM, make the compression rate close to the ideal value of 2.8x
- ~~Avoid swapping latency intensive processes, such as `system_server`, `systemui` and `launcher`~~
- Customizable ZRAM size, ranging from 0G to 6G, please edit `/sdcard/qti_mem_panel.txt` after install

中文版:
- 移除 QTI ActivityManager CUR_MAX_EMPTY_PROCESSES 最大空进程数量的限制
- lowmemorykiller 倾向于保留 adj < 950 的进程
- lowmemorykiller 倾向于结束 adj >= 950 的进程
- 禁止当`vmpressure >= 90`时激进地清理后台
- 较高的低内存水位线降低触发直接内存分配的概率
- 避免把延迟敏感的进程移入ZRAM,比如Android系统服务、Android系统界面和桌面
- 纯粹的内存管理优化模块,不含其它大杂烩,支持骁龙主流平台
- 解决即使剩余内存较多,后台也挂不住的问题,通过移除最大空进程数量(CUR_MAX_EMPTY_PROCESSES)的限制
- 禁止当`vmpressure >= 90`时自适应LMK激进地清理后台
- 减轻高内存压力下掉帧,lowmemorykiller 倾向于结束 adj >= 950 的进程,使文件页面缓存保持在较高水平
- 减轻高内存压力下卡屏,较高的低内存水位线,降低触发直接内存分配的概率
- 避免难以压缩的内存页移入ZRAM,使得压缩率接近理想值2.8x
- ~~避免把延迟敏感的进程移入ZRAM,比如系统框架和桌面,通过MEMCG分组swapiness实现~~
- 可自定义的ZRAM大小,较大的值会延长解压缩时间,范围从0GB到6GB,在安装后请修改`/sdcard/qti_mem_panel.txt`

## Note

- Magisk >= 17.0
- 安装模块重启,打开/sdcard/qti_mem_panel.txt修改想要的ZRAM大小,重启后生效
- ZRAM大小默认值,也可自定义
- 3GB内存推荐1.0GB的ZRAM
- 4GB内存推荐1.0GB的ZRAM
- 6GB内存推荐1.5GB的ZRAM
- 8GB内存推荐2.5GB的ZRAM
- 12GB内存推荐0GB的ZRAM
- 一加用户需要关闭“RamBoost启动加速”这个预读器
- 目前不支持ZSWAP
2 changes: 1 addition & 1 deletion common/service.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
# This will make your scripts compatible even if Magisk change its mount point in the future
MODDIR=${0%/*}

/vendor/bin/sh $MODDIR/system/vendor/bin/qti-mem-opt/powercfg_once.sh
$MODDIR/script/powercfg_once.sh
3 changes: 1 addition & 2 deletions common/system.prop
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@
# CUR_MAX_EMPTY_PROCESSES = CUR_MAX_CACHED_PROCESSES/2
# working on android 9, not 10
ro.vendor.qti.sys.fw.bg_apps_limit=600
ro.vendor.qti.sys.fw.bservice_limit=30
ro.vendor.qti.sys.fw.bservice_age=86400
ro.vendor.qti.sys.fw.bservice_limit=60
9 changes: 5 additions & 4 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,10 @@ REPLACE=""

print_modname() {
ui_print ""
ui_print "QTI memory optimization https://github.com/yc9559/qti-mem-opt"
ui_print "QTI memory optimization"
ui_print "https://github.com/yc9559/qti-mem-opt"
ui_print "Author: Matt Yang"
ui_print "Version: v1 (20191214)"
ui_print "Version: v2 (20191221)"
ui_print ""
}

Expand All @@ -135,6 +136,7 @@ on_install() {
ui_print "- The platform of this device is $target"
ui_print "- Extracting module files"
unzip -o "$ZIPFILE" 'system/*' -d $MODPATH >&2
unzip -o "$ZIPFILE" 'script/*' -d $MODPATH >&2
}

# Only some special files require specific permissions
Expand All @@ -143,14 +145,13 @@ on_install() {

set_permissions() {
# The following is the default rule, DO NOT remove
set_perm_recursive $MODPATH 0 0 0755 0644
set_perm_recursive $MODPATH 0 0 0755 0755

# Here are some examples:
# set_perm_recursive $MODPATH/system/lib 0 0 0755 0644
# set_perm $MODPATH/system/bin/app_process32 0 2000 0755 u:object_r:zygote_exec:s0
# set_perm $MODPATH/system/bin/dex2oat 0 2000 0755 u:object_r:dex2oat_exec:s0
# set_perm $MODPATH/system/lib/libart.so 0 0 0644
set_perm $MODDIR/system/vendor/bin/qti-mem-opt/powercfg_once.sh 0 2000 0755 u:object_r:vendor_file:s0
}

# You can add more functions to assist your custom script code
2 changes: 1 addition & 1 deletion module.prop
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
id=qti-mem-opt
name=QTI memory optimization
version=v1 (20191214)
version=v2 (20191221)
versionCode=1
author=Matt Yang
description=Memory management optimaization for Qualcomm platform. Repo: https://github.com/yc9559/qti-mem-opt
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#! /vendor/bin/sh
#! /system/bin/sh
# Powercfg Library
# https://github.com/yc9559/
# Author: Matt Yang
# Version: 20191214
# Version: 20191221

###############################
# PATHs
###############################

module_dir="/data/adb/modules/qti-mem-opt"
script_rel=/system/vendor/bin/qti-mem-opt
perfcfg_rel=/system/vendor/etc/perf
script_rel="./script"
perfcfg_rel="/system/vendor/etc/perf"
panel_path="/sdcard/qti_mem_panel.txt"

###############################
Expand All @@ -24,6 +24,8 @@ cpu_dev=/sys/devices/system/cpu
ksgl=/sys/class/kgsl/kgsl-3d0
devfreq=/sys/class/devfreq
lpm=/sys/module/lpm_levels/parameters
vm=/proc/sys/vm
lmk=/sys/module/lowmemorykiller/parameters

###############################
# Basic tool functions
Expand Down Expand Up @@ -84,6 +86,17 @@ read_cfg_value()
echo $value
}

# $1:content
write_panel()
{
echo "$1" >> $panel_path
}

clear_panel()
{
true > $panel_path
}

wait_until_login()
{
# we doesn't have the permission to rw "/sdcard" before the user unlocks the screen
Expand Down
196 changes: 196 additions & 0 deletions script/powercfg_once.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
#! /system/bin/sh
# QTI memory optimization
# https://github.com/yc9559/qti-mem-opt
# Author: Matt Yang
# Version: v2 (20191221)

# Runonce after boot, to speed up the transition of power modes in powercfg

# load lib
module_dir="/data/adb/modules/qti-mem-opt"
script_rel="./script"
. $module_dir/$script_rel/powercfg_lib.sh

MemTotalStr=`cat /proc/meminfo | grep MemTotal`
MemTotal=${MemTotalStr:16:8}
zram_size="0"

config_minfree()
{
minfree=""
# <= 4GB
if [ $MemTotal -le 4197304 ]; then
minfree="19200,25600,76800,102400,128000,153600"
# == 6GB
elif [ $MemTotal -le 6291456 ]; then
minfree="19200,25600,128000,153600,179200,204800"
# == 8GB
elif [ $MemTotal -le 8388608 ]; then
minfree="19200,25600,179200,204800,230400,256000"
# > 8GB
else
minfree="19200,25600,256000,307200,358400,409600"
fi

# minfree unit(page size): 4K
lock_val "$minfree" $lmk/minfree
}

# $return:value(string)
calc_zram_default_size()
{
value=""
# <= 4GB
if [ $MemTotal -le 4197304 ]; then
value="1"
# == 6GB
elif [ $MemTotal -le 6291456 ]; then
value="1.5"
# == 8GB
elif [ $MemTotal -le 8388608 ]; then
value="2.5"
# >= 8GB
else
value="0"
fi
echo $value
}

stop_zram()
{
# LG devices may have 2 zram block devices
/system/bin/swapoff /dev/block/zram0
/vendor/bin/swapoff /dev/block/zram0
/system/bin/swapoff /dev/block/zram1
/vendor/bin/swapoff /dev/block/zram1
mutate "1" /sys/block/zram0/reset
mutate "1" /sys/block/zram1/reset
mutate "0" /sys/block/zram0/disksize
mutate "0" /sys/block/zram0/mem_limit
mutate "0" /sys/block/zram1/disksize
mutate "0" /sys/block/zram1/mem_limit
}

# $1:disksize $2:mem_lim
start_zram()
{
stop_zram
# do not touch comp_algorithm, somebody may prefer zstd
# usually not shipped with stock kernels
# lock_val "lz4" /sys/block/zram0/comp_algorithm
# bigger zram means more blocked IO caused by the zram block device swapping out
lock_val $1 /sys/block/zram0/disksize
lock_val $2 /sys/block/zram0/mem_limit
# fix compatibility issues
/system/bin/mkswap /dev/block/zram0
/vendor/bin/mkswap /dev/block/zram0
/system/bin/swapon /dev/block/zram0 -p 23333
/vendor/bin/swapon /dev/block/zram0 -p 23333
# zram doesn't need much read ahead(random read)
lock_val "0" /sys/block/zram0/queue/read_ahead_kb
lock_val "0" $vm/page-cluster
}

config_zram()
{
# load size from file
zram_size=`read_cfg_value zram_size`
case "$zram_size" in
"0.0"|"0"|"0.5"|"1.0"|"1"|"1.5"|"2.0"|"2"|"2.5"|"3.0"|"3"|"4.0"|"4"|"5.0"|"5"|"6.0"|"6")
;;
*)
zram_size=`calc_zram_default_size`
;;
esac

# ~2.8x compression ratio
# higher disksize result in larger space-inefficient SwapCache
case "$zram_size" in
"0.0"|"0")
stop_zram
;;
"0.5")
start_zram 512M 160M
;;
"1.0"|"1")
start_zram 1024M 360M
;;
"1.5")
start_zram 1536M 540M
;;
"2.0"|"2")
start_zram 2048M 720M
;;
"2.5")
start_zram 2560M 900M
;;
"3.0"|"3")
start_zram 3072M 1080M
;;
"4.0"|"4")
start_zram 4096M 1440M
;;
"5.0"|"5")
start_zram 5120M 1800M
;;
"6.0"|"6")
start_zram 6144M 2160M
;;
esac
}

save_panel()
{
clear_panel
write_panel ""
write_panel "QTI memory optimization"
write_panel "https://github.com/yc9559/qti-mem-opt"
write_panel "Author: Matt Yang"
write_panel "Version: v2 (20191221)"
write_panel ""
write_panel "[current status]"
write_panel "ZRAM size: $zram_size"
write_panel "Last: `date '+%Y-%m-%d %H:%M:%S'`"
write_panel ""
write_panel "[settings]"
write_panel "# Available size(GB): 0 / 0.5 / 1 / 1.5 / 2 / 2.5 / 3 / 4 / 5 / 6"
write_panel "zram_size=$zram_size"
write_panel ""
}

# suppress stderr
(

wait_until_login

config_zram

# copy of common\system.prop
setprop ro.vendor.qti.sys.fw.bg_apps_limit 600
setprop ro.vendor.qti.sys.fw.bservice_limit 60

# config traditional LMK
config_minfree
lock_val "0,200,920,930,940,950" $lmk/adj
# disable automatic kill when vmpressure >= 90
lock_val "0" $lmk/enable_adaptive_lmk
# please kill all the processes we really don't want when vmpressure >= 90
# lock_val "960" $lmk/adj_max_shift
# shorter shrinker(LMK) calling interval
lock_val "16" $lmk/cost

# higher watermark_mid reduces direct memory allocation
# 7477M, watermark_mid - watermark_min = 124M
lock_val "32768" $vm/min_free_kbytes
lock_val "51200" $vm/extra_free_kbytes
# lower to reduce useless page swapping
lock_val "100" $vm/watermark_scale_factor
# more room for page cache
lock_val "100" $vm/swappiness
lock_val "120" $vm/vfs_cache_pressure

# save mode for automatic applying mode after reboot
save_panel

# suppress stderr
) 2> /dev/null
Loading

0 comments on commit 632be15

Please sign in to comment.