OpenHarmony 3.2 内存压缩配置说明

仓库主页及介绍 https://gitee.com/openharmony/resourceschedule_memmgr

使能ZRAM

内核选项

启用内存压缩zram,需要通过编译内核时打开相应的配置项及依赖,相关CONFIG如下:

CONFIG_HYPERHOLD=y                  // Enable HyperHold
CONFIG_HYPERHOLD_DEBUG=y            // Enable HyperHold Debug
CONFIG_HYPERHOLD_ZSWAPD=y           // Enable zswapd thread to reclaim anon pages in background
CONFIG_HYPERHOLD_FILE_LRU=y         // Enable HyperHold FILE LRU
CONFIG_HYPERHOLD_MEMCG=y            // Enable Memcg Management in HyperHold
CONFIG_ZRAM_GROUP=y                 // Enable Manage Zram objs with mem_cgroup
CONFIG_ZRAM_GROUP_DEBUG=y           // Enable Manage Zram objs with mem_cgroup Debug
CONFIG_ZLIST_DEBUG=y                // Enable Debug info for zram group list
CONFIG_ZRAM_GROUP_WRITEBACK=y       // Enable Write back grouped zram objs to Hyperhold driver

其中ZRAM_GROUP相关选项非必选。同时,还需依赖以下CONFIG:

CONFIG_MEMCG=y       // Enable Memory controller
CONFIG_SWAP=y        // Enable Support for paging of anonymous memory (swap)
CONFIG_ZSMALLOC=y    // Enable Memory allocator for compressed pages
CONFIG_ZRAM=y        // Enable Compressed RAM block device support

zram设备配置

配置并启用zram设备的代码位于设备device目录下,如对于RK3568,其位于device/board/hihope/rk3568/cfg/init.rk3568.cfg

write /sys/block/zram0/disksize 1024M
mkswap /dev/block/zram0
swapon /dev/block/zram0

查看zram设备

通过如下命令查看zram设备的大小:

# cat /proc/meminfo
MemTotal:        2002200 kB
MemFree:         1072980 kB
MemAvailable:    1440684 kB
Buffers:            1296 kB
Cached:           381896 kB
SwapCached:            0 kB
Active:            69604 kB
Inactive:         589716 kB
Active(anon):        380 kB
Inactive(anon):   302104 kB
Active(file):      69224 kB
Inactive(file):   287612 kB
Active(purg):          0 kB
Inactive(purg):        0 kB
Pined(purg):           0 kB
Unevictable:       26200 kB
Mlocked:               0 kB
SwapTotal:       1048572 kB
SwapFree:        1048572 kB
Dirty:               336 kB
Writeback:             0 kB
AnonPages:        302332 kB
Mapped:           232224 kB
Shmem:             26424 kB
KReclaimable:      51828 kB
Slab:             116396 kB
SReclaimable:      51828 kB
SUnreclaim:        64568 kB
KernelStack:       18368 kB
PageTables:         7700 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     2049672 kB
Committed_AS:     955512 kB
VmallocTotal:   262930368 kB
VmallocUsed:       28128 kB
VmallocChunk:          0 kB
Percpu:              832 kB
Skb:                   0 kB
CmaTotal:          16384 kB
CmaFree:               0 kB
GLTrack:               - kB
ZspageUsed:           12 kB

其中,SwapTotal即为zram大小,SwapFree为可用大小。或通过:

# free -m
                total        used        free      shared     buffers
Mem:             1955         900        1054          25           1
-/+ buffers/cache:            899        1056
Swap:            1023           0        1023

其中swap一行即为zram大小信息。

可用buffer

buffer指标用来衡量当前系统资源提供内存的能力,内存回收与查杀均基于系统的可用buffer,当前系统的了用buffer可通过如下命令查看:

# cat /dev/memcg/memory.zswapd_pressure_show
buffer_size:1351
recent_refault:0

配置说明

配置文件

文件位置

配置文件位于代码的foundation/resourceschedule/memmgr/profile/memmgr_config.xml

位于设备的/etc/memmgr/memmgr_config.xml

替换文件

修改好memmgr_config.xml后,将其推到设备的/etc/memmgr/下并重启即可:

hdc shell mount -o remount,rw /
hdc file send 本地文件路径 /etc/memmgr/memmgr_config.xml
hdc shell reboot

触发时机

当检测到当前可用buffer低于min_avail_buffers时则会唤醒zswapd进行匿名页回收,min_avail_buffers的值可通过:

# cat /dev/memcg/memory.avail_buffers
avail_buffers: 300
min_avail_buffers: 250
high_avail_buffers: 350
free_swap_threshold: 200

将每项都设置为0即可关闭zram:

# cat /dev/memcg/memory.avail_buffers
avail_buffers: 0
min_avail_buffers: 0
high_avail_buffers: 0
free_swap_threshold: 0

availBufferConfig

avail_buffers可通过availBufferConfig来配置,配置的值会写入/dev/memcg/memory.avail_buffers中:

<Memmgr>
  <availBufferConfig>
      <availBuffer>300</availBuffer>
      <minAvailBuffer>250</minAvailBuffer>
      <highAvailBuffer>350</highAvailBuffer>
      <swapReserve>200</swapReserve>
  </availBufferConfig>
</Memmgr>
minAvailBuffer

最小可用buffer值,当前的buffer低于该值会启动匿名页回收。

highAvailBuffer

期望可用buffer值,当启动内存回收后,回收量为highAvailBuffer与当前系统buffer值得差值。比如当前可用buffer为200,按当前配置,低于minAvailBuffer 250时,启动回收,回收期望值为350 - 200 = 150

availBuffer与swapReserve
  • availBuffer:内存正常状态不的buffer值

  • swapReserve:交换分区空闲容量的阈值

当zswapd唤醒并进行内存回收之后,会根据回收后的可用buffer、以及availBuffer与swapReserve的设置记录当前内存压力事件,如LEVEL_LOW、LEVEL_CRITICAL等,并通过eventfd_signal发送事件到用户态。

reclaimConfig

通过reclaimConfig可以配置memcg,如压缩、换出的比例。

<Memmgr>
  <reclaimConfig>
    <ZswapdParam id="1">
        <minScore>0</minScore>
        <maxScore>1000</maxScore>
        <mem2zramRatio>60</mem2zramRatio>
        <zram2ufsRatio>10</zram2ufsRatio>
        <refaultThreshold>50</refaultThreshold>
    </ZswapdParam>
  </reclaimConfig>
</Memmgr>

ZswapdParam

ZswapdParam中可以通过minScore、maxScore设定的范围,匹配不同的回收优先级。

minScore、maxScore

指定当前param匹配的优先级的范围

mem2zramRatio

内存压缩到ZRAM的比率,如果压缩比率大于了该比率,则跳过该次回收,并发送ZSWAPD_MEMCG_RATIO_SKIP事件

zram2ufsRatio

ZRAM换出到ESwap的比率

refaultThreshold

refault的阈值。如果两次操作之间refault超过了阈值,则跳过当次回收,并发送ZSWAPD_MEMCG_REFAULT_SKIP事件

查看应用回收优先级

通过如下命令查看应用属于哪个cgroup,xxxx替换为应用pid:

# cat /proc/xxxx/cgroup
4:freezer:/
3:memory:/100
2:cpu:/
1:cpuset:/

3:memory:/100中的/100指明了cgroup的相对路径,即/dev/memcg/100。通过如下命令查看该cgroup的回收优先级:

# cat /dev/memcg/100/memory.app_score
0

按示例的ZswapdParam,会匹配到id为1的配置。

也可以通过如下命令查看100的memcg配置:

# cat /dev/memcg/100/memory.zswapd_single_memcg_param
memcg score: 0
memcg ub_mem2zram_ratio: 60
memcg ub_zram2ufs_ratio: 10
memcg refault_threshold: 50

zswapd_single_memcg_param与zswapd_memcgs_param

配置文件中的reclaimConfig会写入zswapd_memcgs_param中

# cat /dev/memcg/memory.zswapd_memcgs_param
level 0 min score: 0
level 0 max score: 1000
level 0 ub_mem2zram_ratio: 60
level 0 ub_zram2ufs_ratio: 10
level 0 refault_threshold: 50
level 1 min score: 0
level 1 max score: 0
level 1 ub_mem2zram_ratio: 0
level 1 ub_zram2ufs_ratio: 0
level 1 refault_threshold: 0
level 2 min score: 0
level 2 max score: 0
level 2 ub_mem2zram_ratio: 0
level 2 ub_zram2ufs_ratio: 0
level 2 refault_threshold: 0
level 3 min score: 0
level 3 max score: 0
level 3 ub_mem2zram_ratio: 0
level 3 ub_zram2ufs_ratio: 0
level 3 refault_threshold: 0
level 4 min score: 0
level 4 max score: 0
level 4 ub_mem2zram_ratio: 0
level 4 ub_zram2ufs_ratio: 0
level 4 refault_threshold: 0
level 5 min score: 0
level 5 max score: 0
level 5 ub_mem2zram_ratio: 0
level 5 ub_zram2ufs_ratio: 0
level 5 refault_threshold: 0
level 6 min score: 0
level 6 max score: 0
level 6 ub_mem2zram_ratio: 0
level 6 ub_zram2ufs_ratio: 0
level 6 refault_threshold: 0
level 7 min score: 0
level 7 max score: 0
level 7 ub_mem2zram_ratio: 0
level 7 ub_zram2ufs_ratio: 0
level 7 refault_threshold: 0
level 8 min score: 0
level 8 max score: 0
level 8 ub_mem2zram_ratio: 0
level 8 ub_zram2ufs_ratio: 0
level 8 refault_threshold: 0
level 9 min score: 0
level 9 max score: 0
level 9 ub_mem2zram_ratio: 0
level 9 ub_zram2ufs_ratio: 0
level 9 refault_threshold: 0

内核会通过读取memcg的优先级,再根据上面的列表,配置到zswapd_single_memcg_param中。

账户

每个账户都会创建一个memcg。如/dev/memcg/100就是100号用户,0号用户使用的是/dev/memcg。账户的回收优先级通过memory.app_score查看,回收阈值等通过memory.zswapd_single_memcg_param查看

  • 账户的默认回收优先级为300

  • active状态下的账户优先级为0

  • inactive状态下的账户优先级为50

ESwap

ESwap可以将zram压缩后的匿名页加密换出到ESwap存储分区,从而能完全的空出一块可用内存,以此来达到维持Memavailable水线的目标,ESwap使能方法可以参考:https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/kernel/kernel-standard-mm-eswap.md

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐