特性来源
ALMK: adaptive lowmemorykiller,是Qualcomm针对安卓LMK的优化,当系统lmk还没有杀进程时,如果发现有过高的vmpressure,就有可能会造成卡顿,此时杀掉某个进程是个比较好的选择。
代码分析
msm kernel3.18 lowmemorykiller.c 主体函数如下:
static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) { ... for (i = 0; i < array_size; i++) { minfree = lowmem_minfree[i]; if (other_free < minfree && other_file < minfree) { min_score_adj = lowmem_adj[i]; break; } } ret = adjust_minadj(&min_score_adj); ... }
|
在minfree的范围判断后加入了min_score_adj的调整,代码如下:
int adjust_minadj(short *min_score_adj) { int ret = VMPRESSURE_NO_ADJUST; if (!enable_adaptive_lmk) return 0; if (atomic_read(&shift_adj) && (*min_score_adj > adj_max_shift)) { if (*min_score_adj == OOM_SCORE_ADJ_MAX + 1) ret = VMPRESSURE_ADJUST_ENCROACH; else ret = VMPRESSURE_ADJUST_NORMAL; *min_score_adj = adj_max_shift; } atomic_set(&shift_adj, 0); return ret; }
|
enable_adaptive_lmk是特性开关。
shift_adj用作入口首要条件,>0才能进入,这个会在vm pressure中set,等下来看。
同时,lmk所选择的min_score_adj要>adj_max_shift才能working,比如如果系统内存在minfree之上时,此时的adjust_minadj就是VMPRESSURE_ADJUST_ENCROACH.
下面的代码就是如何用vmpressure探测系统thrashing:
static int lmk_vmpressure_notifier(struct notifier_block *nb, unsigned long action, void *data) { int other_free, other_file; unsigned long pressure = action; int array_size = ARRAY_SIZE(lowmem_adj); if (!enable_adaptive_lmk) return 0; if (pressure >= 95) { other_file = global_page_state(NR_FILE_PAGES) + zcache_pages() - global_page_state(NR_SHMEM) - total_swapcache_pages(); other_free = global_page_state(NR_FREE_PAGES); atomic_set(&shift_adj, 1); trace_almk_vmpressure(pressure, other_free, other_file); } else if (pressure >= 90) { if (lowmem_adj_size < array_size) array_size = lowmem_adj_size; if (lowmem_minfree_size < array_size) array_size = lowmem_minfree_size; other_file = global_page_state(NR_FILE_PAGES) + zcache_pages() - global_page_state(NR_SHMEM) - total_swapcache_pages(); other_free = global_page_state(NR_FREE_PAGES); if ((other_free < lowmem_minfree[array_size - 1]) && (other_file < vmpressure_file_min)) { atomic_set(&shift_adj, 1); trace_almk_vmpressure(pressure, other_free, other_file); } }
|
这段代码里的90,95有code style问题,在vmpressure.c有如下级别定义:
static const unsigned int vmpressure_level_med = 60;
static const unsigned int vmpressure_level_critical = 95;
这里的95就表明系统基本上page thrashing了,要释放内存。至于90可以理解为incoming状态,提前发现问题,也符合lmk思想。
对于95以上的,shift_adj直接置1了。
对于90-94之间的,要满足一定条件才能触发,很明显,相比lowmem_scan,这里就把空进程的minfree换成了vmpressure_file_min。
为了保证在空进程时系统thrashing也能杀进程,一般vmpressure_file_min要高于minfree max。
版权声明:本站所有文章均采用 CC BY-NC-SA 4.0 CN 许可协议。转载请注明原文链接!