1*f0abc76dSxu xin.. include:: ../../disclaimer-zh_CN.rst
2*f0abc76dSxu xin
3*f0abc76dSxu xin:Original: Documentation/admin-guide/mm/ksm.rst
4*f0abc76dSxu xin
5*f0abc76dSxu xin:翻译:
6*f0abc76dSxu xin
7*f0abc76dSxu xin  徐鑫 xu xin <xu.xin16@zte.com.cn>
8*f0abc76dSxu xin
9*f0abc76dSxu xin
10*f0abc76dSxu xin============
11*f0abc76dSxu xin内核同页合并
12*f0abc76dSxu xin============
13*f0abc76dSxu xin
14*f0abc76dSxu xin
15*f0abc76dSxu xin概述
16*f0abc76dSxu xin====
17*f0abc76dSxu xin
18*f0abc76dSxu xinKSM是一种能节省内存的数据去重功能,由CONFIG_KSM=y启用,并在2.6.32版本时被添
19*f0abc76dSxu xin加到Linux内核。详见 ``mm/ksm.c`` 的实现,以及http://lwn.net/Articles/306704
20*f0abc76dSxu xinhttps://lwn.net/Articles/330589
21*f0abc76dSxu xin
22*f0abc76dSxu xinKSM最初目的是为了与KVM(即著名的内核共享内存)一起使用而开发的,通过共享虚拟机
23*f0abc76dSxu xin之间的公共数据,将更多虚拟机放入物理内存。但它对于任何会生成多个相同数据实例的
24*f0abc76dSxu xin应用程序都是很有用的。
25*f0abc76dSxu xin
26*f0abc76dSxu xinKSM的守护进程ksmd会定期扫描那些已注册的用户内存区域,查找内容相同的页面,这些
27*f0abc76dSxu xin页面可以被单个写保护页面替换(如果进程以后想要更新其内容,将自动复制)。使用:
28*f0abc76dSxu xin引用:`sysfs intraface  <ksm_sysfs>` 接口来配置KSM守护程序在单个过程中所扫描的页
29*f0abc76dSxu xin数以及两个过程之间的间隔时间。
30*f0abc76dSxu xin
31*f0abc76dSxu xinKSM只合并匿名(私有)页面,从不合并页缓存(文件)页面。KSM的合并页面最初只能被
32*f0abc76dSxu xin锁定在内核内存中,但现在可以就像其他用户页面一样被换出(但当它们被交换回来时共
33*f0abc76dSxu xin享会被破坏: ksmd必须重新发现它们的身份并再次合并)。
34*f0abc76dSxu xin
35*f0abc76dSxu xin以madvise控制KSM
36*f0abc76dSxu xin================
37*f0abc76dSxu xin
38*f0abc76dSxu xinKSM仅在特定的地址空间区域时运行,即应用程序通过使用如下所示的madvise(2)系统调
39*f0abc76dSxu xin用来请求某块地址成为可能的合并候选者的地址空间::
40*f0abc76dSxu xin
41*f0abc76dSxu xin    int madvise(addr, length, MADV_MERGEABLE)
42*f0abc76dSxu xin
43*f0abc76dSxu xin应用程序当然也可以通过调用::
44*f0abc76dSxu xin
45*f0abc76dSxu xin    int madvise(addr, length, MADV_UNMERGEABLE)
46*f0abc76dSxu xin
47*f0abc76dSxu xin来取消该请求,并恢复为非共享页面:此时KSM将去除合并在该范围内的任何合并页。注意:
48*f0abc76dSxu xin这个去除合并的调用可能突然需要的内存量超过实际可用的内存量-那么可能会出现EAGAIN
49*f0abc76dSxu xin失败,但更可能会唤醒OOM killer。
50*f0abc76dSxu xin
51*f0abc76dSxu xin如果KSM未被配置到正在运行的内核中,则madvise MADV_MERGEABLE 和 MADV_UNMERGEABLE
52*f0abc76dSxu xin的调用只会以EINVAL 失败。如果正在运行的内核是用CONFIG_KSM=y方式构建的,那么这些
53*f0abc76dSxu xin调用通常会成功:即使KSM守护程序当前没有运行,MADV_MERGEABLE 仍然会在KSM守护程序
54*f0abc76dSxu xin启动时注册范围,即使该范围不能包含KSM实际可以合并的任何页面,即使MADV_UNMERGEABLE
55*f0abc76dSxu xin应用于从未标记为MADV_MERGEABLE的范围。
56*f0abc76dSxu xin
57*f0abc76dSxu xin如果一块内存区域必须被拆分为至少一个新的MADV_MERGEABLE区域或MADV_UNMERGEABLE区域,
58*f0abc76dSxu xin当该进程将超过 ``vm.max_map_count`` 的设定,则madvise可能返回ENOMEM。(请参阅文档
59*f0abc76dSxu xinDocumentation/admin-guide/sysctl/vm.rst)。
60*f0abc76dSxu xin
61*f0abc76dSxu xin与其他madvise调用一样,它们在用户地址空间的映射区域上使用:如果指定的范围包含未
62*f0abc76dSxu xin映射的间隙(尽管在中间的映射区域工作),它们将报告ENOMEM,如果没有足够的内存用于
63*f0abc76dSxu xin内部结构,则可能会因EAGAIN而失败。
64*f0abc76dSxu xin
65*f0abc76dSxu xinKSM守护进程sysfs接口
66*f0abc76dSxu xin====================
67*f0abc76dSxu xin
68*f0abc76dSxu xinKSM守护进程可以由``/sys/kernel/mm/ksm/`` 中的sysfs文件控制,所有人都可以读取,但
69*f0abc76dSxu xin只能由root用户写入。各接口解释如下:
70*f0abc76dSxu xin
71*f0abc76dSxu xin
72*f0abc76dSxu xinpages_to_scan
73*f0abc76dSxu xin        ksmd进程进入睡眠前要扫描的页数。
74*f0abc76dSxu xin        例如, ``echo 100 > /sys/kernel/mm/ksm/pages_to_scan``
75*f0abc76dSxu xin
76*f0abc76dSxu xin        默认值:100(该值被选择用于演示目的)
77*f0abc76dSxu xin
78*f0abc76dSxu xinsleep_millisecs
79*f0abc76dSxu xin        ksmd在下次扫描前应休眠多少毫秒
80*f0abc76dSxu xin        例如, ``echo 20 > /sys/kernel/mm/ksm/sleep_millisecs``
81*f0abc76dSxu xin
82*f0abc76dSxu xin        默认值:20(该值被选择用于演示目的)
83*f0abc76dSxu xin
84*f0abc76dSxu xinmerge_across_nodes
85*f0abc76dSxu xin        指定是否可以合并来自不同NUMA节点的页面。当设置为0时,ksm仅合并在物理上位
86*f0abc76dSxu xin        于同一NUMA节点的内存区域中的页面。这降低了访问共享页面的延迟。在有明显的
87*f0abc76dSxu xin        NUMA距离上,具有更多节点的系统可能受益于设置该值为0时的更低延迟。而对于
88*f0abc76dSxu xin        需要对内存使用量最小化的较小系统来说,设置该值为1(默认设置)则可能会受
89*f0abc76dSxu xin        益于更大共享页面。在决定使用哪种设置之前,您可能希望比较系统在每种设置下
90*f0abc76dSxu xin        的性能。 ``merge_across_nodes`` 仅当系统中没有ksm共享页面时,才能被更改设
91*f0abc76dSxu xin        置:首先将接口`run` 设置为2从而对页进行去合并,然后在修改
92*f0abc76dSxu xin        ``merge_across_nodes`` 后再将‘run’又设置为1,以根据新设置来重新合并。
93*f0abc76dSxu xin
94*f0abc76dSxu xin        默认值:1(如早期的发布版本一样合并跨站点)
95*f0abc76dSxu xin
96*f0abc76dSxu xinrun
97*f0abc76dSxu xin        * 设置为0可停止ksmd运行,但保留合并页面,
98*f0abc76dSxu xin        * 设置为1可运行ksmd,例如, ``echo 1 > /sys/kernel/mm/ksm/run`` ,
99*f0abc76dSxu xin        * 设置为2可停止ksmd运行,并且对所有目前已合并的页进行去合并,但保留可合并
100*f0abc76dSxu xin          区域以供下次运行。
101*f0abc76dSxu xin
102*f0abc76dSxu xin        默认值:0(必须设置为1才能激活KSM,除非禁用了CONFIG_SYSFS)
103*f0abc76dSxu xin
104*f0abc76dSxu xinuse_zero_pages
105*f0abc76dSxu xin        指定是否应当特殊处理空页(即那些仅含zero的已分配页)。当该值设置为1时,
106*f0abc76dSxu xin        空页与内核零页合并,而不是像通常情况下那样空页自身彼此合并。这可以根据
107*f0abc76dSxu xin        工作负载的不同,在具有着色零页的架构上可以提高性能。启用此设置时应小心,
108*f0abc76dSxu xin        因为它可能会降低某些工作负载的KSM性能,比如,当待合并的候选页面的校验和
109*f0abc76dSxu xin        与空页面的校验和恰好匹配的时候。此设置可随时更改,仅对那些更改后再合并
110*f0abc76dSxu xin        的页面有效。
111*f0abc76dSxu xin
112*f0abc76dSxu xin        默认值:0(如同早期版本的KSM正常表现)
113*f0abc76dSxu xin
114*f0abc76dSxu xinmax_page_sharing
115*f0abc76dSxu xin        单个KSM页面允许的最大共享站点数。这将强制执行重复数据消除限制,以避免涉
116*f0abc76dSxu xin        及遍历共享KSM页面的虚拟映射的虚拟内存操作的高延迟。最小值为2,因为新创
117*f0abc76dSxu xin        建的KSM页面将至少有两个共享者。该值越高,KSM合并内存的速度越快,去重
118*f0abc76dSxu xin        因子也越高,但是对于任何给定的KSM页面,虚拟映射的最坏情况遍历的速度也会
119*f0abc76dSxu xin        越慢。减慢了这种遍历速度就意味着在交换、压缩、NUMA平衡和页面迁移期间,
120*f0abc76dSxu xin        某些虚拟内存操作将有更高的延迟,从而降低这些虚拟内存操作调用者的响应能力。
121*f0abc76dSxu xin        其他任务如果不涉及执行虚拟映射遍历的VM操作,其任务调度延迟不受此参数的影
122*f0abc76dSxu xin        响,因为这些遍历本身是调度友好的。
123*f0abc76dSxu xin
124*f0abc76dSxu xinstable_node_chains_prune_millisecs
125*f0abc76dSxu xin        指定KSM检查特定页面的元数据的频率(即那些达到过时信息数据去重限制标准的
126*f0abc76dSxu xin        页面)单位是毫秒。较小的毫秒值将以更低的延迟来释放KSM元数据,但它们将使
127*f0abc76dSxu xin        ksmd在扫描期间使用更多CPU。如果还没有一个KSM页面达到 ``max_page_sharing``
128*f0abc76dSxu xin        标准,那就没有什么用。
129*f0abc76dSxu xin
130*f0abc76dSxu xinKSM与MADV_MERGEABLE的工作有效性体现于 ``/sys/kernel/mm/ksm/`` 路径下的接口:
131*f0abc76dSxu xin
132*f0abc76dSxu xinpages_shared
133*f0abc76dSxu xin        表示多少共享页正在被使用
134*f0abc76dSxu xinpages_sharing
135*f0abc76dSxu xin        表示还有多少站点正在共享这些共享页,即节省了多少
136*f0abc76dSxu xinpages_unshared
137*f0abc76dSxu xin        表示有多少页是唯一的,但被反复检查以进行合并
138*f0abc76dSxu xinpages_volatile
139*f0abc76dSxu xin        表示有多少页因变化太快而无法放在tree中
140*f0abc76dSxu xinfull_scans
141*f0abc76dSxu xin        表示所有可合并区域已扫描多少次
142*f0abc76dSxu xinstable_node_chains
143*f0abc76dSxu xin        达到 ``max_page_sharing`` 限制的KSM页数
144*f0abc76dSxu xinstable_node_dups
145*f0abc76dSxu xin        重复的KSM页数
146*f0abc76dSxu xin
147*f0abc76dSxu xin比值 ``pages_sharing/pages_shared`` 的最大值受限制于 ``max_page_sharing``
148*f0abc76dSxu xin的设定。要想增加该比值,则相应地要增加 ``max_page_sharing`` 的值。
149