首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

[linux][memory]KSM技术分析

前言: 先来回顾一下Linux平台上的节约内存的方案: swap:通过LRU淘汰掉掉一部分page,把这些page交换到磁盘上。再次访问到这些page的时候,kernel再把它们从磁盘load进内存中。 zram:内存压缩技术。通过压缩lzo算法把页面压缩,也可以节省一部分内存。作者第一次知道zram是在Android中见到的,因为一般的手机使用的emmc flash,是有读写寿命的(作者看到过一份实验数据,某厂家的emmc在连续写入数据三天后,emmc就已经挂了),不能打开swap(因为swap会增加大量的io访问,会让emmc硬件老化更快)。在服务器领域上,作者对这个技术并不是很乐观。 COW:copy-on-write技术,既能减少不必要的运算(这里的减少指的是memory copy;当然,COW触发的时候,需要处理page fault),又能减少内存的使用。 Shared link:用户态能做到的。Linux上几乎所有的程序都需要使用glibc,那么,如果glibc的代码每个进程都拷贝一份,那么就会造成一定的浪费。动态链接技术则可以保证动态链接的程序共享同一份。 Memory balloon:当然,这个技术只针对于云计算平台。作者在《[linux][memory]balloon技术分析》中的解读。 KSM:Kernel Samepage Merging,内核动态计算,找到内核中相同的页面,把相同的页面进程合并。 本文重点解读KSM技术。 设计: 例如Host中运行了多个运行着相同操作系统的Guest OS,那么这些Guest OS中会有很多相同的page,而且很可能是相对稳定的。例如,每个Guest OS都运行着相同的glibc,ld等,而且这些库的代码段和只读数据区都会被映射成只读的page。那么,就可以把这些相同的page做merge操作,节省Host的内存。

所谓merge,就是让多个使用相同page的进程,共享同一个page,把另外的page释放掉。 代码: 代码路径:linux-4.0.4/mm/ksm.c 1,在linux-4.0.4/mm/madvise.c中,

通过MADV_MERGEABLE/MADV_UNMERGEABLE可以建议kernel做merge或者unmerge。 2,在linux-4.0.4/mm/ksm.c中,

主要创建ksm使用的slab,并启动内核线程ksmd。 3,触发ksm_madvise后,__ksm_enter/unmerge_ksm_pages。

4,__ksm_enter中会先把需要做merge的mm插入到链表中,并唤醒ksmd线程。ksmd的核心函数是ksm_do_scan。

首先通过scan_get_next_rmap_item函数获取到需要做merge的page。再通过cmp_and_merge_page函数做merge操作。 5,cmp_and_merge_page函数实现了page merge。 ksm使用的stable tree,是根据page的memcmp组织的红黑树,stable tree中放入stable page。优先判断page是不是已经在stable tree中。如果在stable tree中找到了相同的page,同一个page就不merge了,不是同一个page就在try_to_merge_with_ksm_page函数中做merge。

6,try_to_merge_with_ksm_page函数中,会继续调用try_to_merge_one_page,再调用replace_page。 即使用从stable中的kpage,替换原来的page。并尝试把原来的page释放掉。

7,cmp_and_merge_page还有另外的一个分支:处理unstable tree。

如果page的checksum频繁变化,那就算了,这样的page不适合做merge。 在unstable tree中查找,是否有相同的page。如果没有,把当前page插入unstable tree中就行; 如果在unstable tree中已经有了,那么就尝试merge,然后挪到stable tree中。 8,如果在madvise中选择MADV_UNMERGEABLE,则会触发unmerge_ksm_pages函数。进一步调用到break_ksm函数:

在这里触发handle_mm_fault即可。原理同COW一致。差别在于:COW是由于CPU写page的时候,发现pte中标记的page不可写,会产生一个exception,在处理exception的时候,判断出来是因为COW,则会分配page给进程。 而KSM则是直接选择使用handle_mm_fault来处理。 后记: 作者第一次阅读ZRAM的代码的时候,就被惊讶到一次:原来还可以这么玩~ 后来看到KSM的时候,再次被惊讶到:原来还可以这么玩~ 只能说:别懈怠,技术的路上,不知道的还很多。

下一篇
举报
领券