.. include:: ../../disclaimer-zh_CN.rst :Original: Documentation/admin-guide/mm/ksm.rst :翻译: å¾é‘« xu xin <xu.xin16@zte.com.cn> ============ å†…æ ¸åŒé¡µåˆå¹¶ ============ 概述 ==== KSM是一ç§èƒ½èŠ‚çœå†…å˜çš„æ•°æ®åŽ»é‡åŠŸèƒ½ï¼Œç”±CONFIG_KSM=yå¯ç”¨ï¼Œå¹¶åœ¨2.6.32版本时被添 åŠ åˆ°Linuxå†…æ ¸ã€‚è¯¦è§ ``mm/ksm.c`` 的实现,以åŠhttp://lwn.net/Articles/306704 å’Œhttps://lwn.net/Articles/330589 KSM最åˆç›®çš„是为了与KVM(å³è‘—åçš„å†…æ ¸å…±äº«å†…å˜ï¼‰ä¸€èµ·ä½¿ç”¨è€Œå¼€å‘的,通过共享虚拟机 之间的公共数æ®ï¼Œå°†æ›´å¤šè™šæ‹Ÿæœºæ”¾å…¥ç‰©ç†å†…å˜ã€‚但它对于任何会生æˆå¤šä¸ªç›¸åŒæ•°æ®å®žä¾‹çš„ 应用程åºéƒ½æ˜¯å¾ˆæœ‰ç”¨çš„。 KSM的守护进程ksmd会定期扫æ那些已注册的用户内å˜åŒºåŸŸï¼ŒæŸ¥æ‰¾å†…容相åŒçš„页é¢ï¼Œè¿™äº› 页é¢å¯ä»¥è¢«å•ä¸ªå†™ä¿æŠ¤é¡µé¢æ›¿æ¢ï¼ˆå¦‚果进程以åŽæƒ³è¦æ›´æ–°å…¶å†…容,将自动å¤åˆ¶ï¼‰ã€‚使用: 引用:`sysfs intraface <ksm_sysfs>` 接å£æ¥é…ç½®KSM守护程åºåœ¨å•ä¸ªè¿‡ç¨‹ä¸æ‰€æ‰«æ的页 数以åŠä¸¤ä¸ªè¿‡ç¨‹ä¹‹é—´çš„间隔时间。 KSMåªåˆå¹¶åŒ¿å(ç§æœ‰ï¼‰é¡µé¢ï¼Œä»Žä¸åˆå¹¶é¡µç¼“å˜ï¼ˆæ–‡ä»¶ï¼‰é¡µé¢ã€‚KSMçš„åˆå¹¶é¡µé¢æœ€åˆåªèƒ½è¢« é”å®šåœ¨å†…æ ¸å†…å˜ä¸ï¼Œä½†çŽ°åœ¨å¯ä»¥å°±åƒå…¶ä»–用户页é¢ä¸€æ ·è¢«æ¢å‡ºï¼ˆä½†å½“它们被交æ¢å›žæ¥æ—¶å…± äº«ä¼šè¢«ç ´å: ksmdå¿…é¡»é‡æ–°å‘现它们的身份并å†æ¬¡åˆå¹¶ï¼‰ã€‚ 以madvise控制KSM ================ KSM仅在特定的地å€ç©ºé—´åŒºåŸŸæ—¶è¿è¡Œï¼Œå³åº”用程åºé€šè¿‡ä½¿ç”¨å¦‚下所示的madvise(2)系统调 用æ¥è¯·æ±‚æŸå—地å€æˆä¸ºå¯èƒ½çš„åˆå¹¶å€™é€‰è€…的地å€ç©ºé—´:: int madvise(addr, length, MADV_MERGEABLE) 应用程åºå½“然也å¯ä»¥é€šè¿‡è°ƒç”¨:: int madvise(addr, length, MADV_UNMERGEABLE) æ¥å–消该请求,并æ¢å¤ä¸ºéžå…±äº«é¡µé¢ï¼šæ¤æ—¶KSM将去除åˆå¹¶åœ¨è¯¥èŒƒå›´å†…的任何åˆå¹¶é¡µã€‚注æ„: 这个去除åˆå¹¶çš„调用å¯èƒ½çªç„¶éœ€è¦çš„内å˜é‡è¶…过实际å¯ç”¨çš„内å˜é‡-那么å¯èƒ½ä¼šå‡ºçŽ°EAGAIN 失败,但更å¯èƒ½ä¼šå”¤é†’OOM killer。 如果KSM未被é…置到æ£åœ¨è¿è¡Œçš„å†…æ ¸ä¸ï¼Œåˆ™madvise MADV_MERGEABLE å’Œ MADV_UNMERGEABLE 的调用åªä¼šä»¥EINVAL 失败。如果æ£åœ¨è¿è¡Œçš„å†…æ ¸æ˜¯ç”¨CONFIG_KSM=yæ–¹å¼æž„建的,那么这些 调用通常会æˆåŠŸï¼šå³ä½¿KSM守护程åºå½“å‰æ²¡æœ‰è¿è¡Œï¼ŒMADV_MERGEABLE ä»ç„¶ä¼šåœ¨KSMå®ˆæŠ¤ç¨‹åº å¯åŠ¨æ—¶æ³¨å†ŒèŒƒå›´ï¼Œå³ä½¿è¯¥èŒƒå›´ä¸èƒ½åŒ…å«KSM实际å¯ä»¥åˆå¹¶çš„任何页é¢ï¼Œå³ä½¿MADV_UNMERGEABLE åº”ç”¨äºŽä»Žæœªæ ‡è®°ä¸ºMADV_MERGEABLE的范围。 如果一å—内å˜åŒºåŸŸå¿…须被拆分为至少一个新的MADV_MERGEABLE区域或MADV_UNMERGEABLE区域, 当该进程将超过 ``vm.max_map_count`` 的设定,则madviseå¯èƒ½è¿”回ENOMEM。(请å‚阅文档 Documentation/admin-guide/sysctl/vm.rst)。 与其他madviseè°ƒç”¨ä¸€æ ·ï¼Œå®ƒä»¬åœ¨ç”¨æˆ·åœ°å€ç©ºé—´çš„æ˜ å°„åŒºåŸŸä¸Šä½¿ç”¨ï¼šå¦‚æžœæŒ‡å®šçš„èŒƒå›´åŒ…å«æœª æ˜ å°„çš„é—´éš™ï¼ˆå°½ç®¡åœ¨ä¸é—´çš„æ˜ å°„åŒºåŸŸå·¥ä½œï¼‰ï¼Œå®ƒä»¬å°†æŠ¥å‘ŠENOMEM,如果没有足够的内å˜ç”¨äºŽ 内部结构,则å¯èƒ½ä¼šå› EAGAIN而失败。 KSM守护进程sysfsæŽ¥å£ ==================== KSM守护进程å¯ä»¥ç”±``/sys/kernel/mm/ksm/`` ä¸çš„sysfs文件控制,所有人都å¯ä»¥è¯»å–,但 åªèƒ½ç”±root用户写入。å„接å£è§£é‡Šå¦‚下: pages_to_scan ksmd进程进入ç¡çœ å‰è¦æ‰«æ的页数。 例如, ``echo 100 > /sys/kernel/mm/ksm/pages_to_scan`` 默认值:100(该值被选择用于演示目的) sleep_millisecs ksmd在下次扫æå‰åº”ä¼‘çœ å¤šå°‘æ¯«ç§’ 例如, ``echo 20 > /sys/kernel/mm/ksm/sleep_millisecs`` 默认值:20(该值被选择用于演示目的) merge_across_nodes 指定是å¦å¯ä»¥åˆå¹¶æ¥è‡ªä¸åŒNUMA节点的页é¢ã€‚当设置为0时,ksmä»…åˆå¹¶åœ¨ç‰©ç†ä¸Šä½ 于åŒä¸€NUMA节点的内å˜åŒºåŸŸä¸çš„页é¢ã€‚è¿™é™ä½Žäº†è®¿é—®å…±äº«é¡µé¢çš„延迟。在有明显的 NUMAè·ç¦»ä¸Šï¼Œå…·æœ‰æ›´å¤šèŠ‚点的系统å¯èƒ½å—益于设置该值为0时的更低延迟。而对于 需è¦å¯¹å†…å˜ä½¿ç”¨é‡æœ€å°åŒ–的较å°ç³»ç»Ÿæ¥è¯´ï¼Œè®¾ç½®è¯¥å€¼ä¸º1(默认设置)则å¯èƒ½ä¼šå— 益于更大共享页é¢ã€‚在决定使用哪ç§è®¾ç½®ä¹‹å‰ï¼Œæ‚¨å¯èƒ½å¸Œæœ›æ¯”较系统在æ¯ç§è®¾ç½®ä¸‹ 的性能。 ``merge_across_nodes`` 仅当系统ä¸æ²¡æœ‰ksm共享页é¢æ—¶ï¼Œæ‰èƒ½è¢«æ›´æ”¹è®¾ 置:首先将接å£`run` 设置为2从而对页进行去åˆå¹¶ï¼Œç„¶åŽåœ¨ä¿®æ”¹ ``merge_across_nodes`` åŽå†å°†â€˜run’åˆè®¾ç½®ä¸º1ï¼Œä»¥æ ¹æ®æ–°è®¾ç½®æ¥é‡æ–°åˆå¹¶ã€‚ 默认值:1(如早期的å‘å¸ƒç‰ˆæœ¬ä¸€æ ·åˆå¹¶è·¨ç«™ç‚¹ï¼‰ run * 设置为0å¯åœæ¢ksmdè¿è¡Œï¼Œä½†ä¿ç•™åˆå¹¶é¡µé¢ï¼Œ * 设置为1å¯è¿è¡Œksmd,例如, ``echo 1 > /sys/kernel/mm/ksm/run`` , * 设置为2å¯åœæ¢ksmdè¿è¡Œï¼Œå¹¶ä¸”对所有目å‰å·²åˆå¹¶çš„页进行去åˆå¹¶ï¼Œä½†ä¿ç•™å¯åˆå¹¶ 区域以供下次è¿è¡Œã€‚ 默认值:0(必须设置为1æ‰èƒ½æ¿€æ´»KSM,除éžç¦ç”¨äº†CONFIG_SYSFS) use_zero_pages 指定是å¦åº”当特殊处ç†ç©ºé¡µï¼ˆå³é‚£äº›ä»…å«zero的已分é…页)。当该值设置为1时, ç©ºé¡µä¸Žå†…æ ¸é›¶é¡µåˆå¹¶ï¼Œè€Œä¸æ˜¯åƒé€šå¸¸æƒ…å†µä¸‹é‚£æ ·ç©ºé¡µè‡ªèº«å½¼æ¤åˆå¹¶ã€‚è¿™å¯ä»¥æ ¹æ® 工作负载的ä¸åŒï¼Œåœ¨å…·æœ‰ç€è‰²é›¶é¡µçš„架构上å¯ä»¥æ高性能。å¯ç”¨æ¤è®¾ç½®æ—¶åº”å°å¿ƒï¼Œ å› ä¸ºå®ƒå¯èƒ½ä¼šé™ä½ŽæŸäº›å·¥ä½œè´Ÿè½½çš„KSM性能,比如,当待åˆå¹¶çš„候选页é¢çš„æ ¡éªŒå’Œ 与空页é¢çš„æ ¡éªŒå’Œæ°å¥½åŒ¹é…的时候。æ¤è®¾ç½®å¯éšæ—¶æ›´æ”¹ï¼Œä»…对那些更改åŽå†åˆå¹¶ 的页é¢æœ‰æ•ˆã€‚ 默认值:0(如åŒæ—©æœŸç‰ˆæœ¬çš„KSMæ£å¸¸è¡¨çŽ°ï¼‰ max_page_sharing å•ä¸ªKSM页é¢å…许的最大共享站点数。这将强制执行é‡å¤æ•°æ®æ¶ˆé™¤é™åˆ¶ï¼Œä»¥é¿å…涉 åŠé历共享KSM页é¢çš„è™šæ‹Ÿæ˜ å°„çš„è™šæ‹Ÿå†…å˜æ“作的高延迟。最å°å€¼ä¸º2ï¼Œå› ä¸ºæ–°åˆ› 建的KSM页é¢å°†è‡³å°‘有两个共享者。该值越高,KSMåˆå¹¶å†…å˜çš„é€Ÿåº¦è¶Šå¿«ï¼ŒåŽ»é‡ å› å也越高,但是对于任何给定的KSM页é¢ï¼Œè™šæ‹Ÿæ˜ 射的最å情况é历的速度也会 越慢。å‡æ…¢äº†è¿™ç§é历速度就æ„味ç€åœ¨äº¤æ¢ã€åŽ‹ç¼©ã€NUMA平衡和页é¢è¿ç§»æœŸé—´ï¼Œ æŸäº›è™šæ‹Ÿå†…å˜æ“作将有更高的延迟,从而é™ä½Žè¿™äº›è™šæ‹Ÿå†…å˜æ“作调用者的å“应能力。 其他任务如果ä¸æ¶‰åŠæ‰§è¡Œè™šæ‹Ÿæ˜ å°„é历的VMæ“作,其任务调度延迟ä¸å—æ¤å‚æ•°çš„å½± å“ï¼Œå› ä¸ºè¿™äº›é历本身是调度å‹å¥½çš„。 stable_node_chains_prune_millisecs 指定KSM检查特定页é¢çš„元数æ®çš„频率(å³é‚£äº›è¾¾åˆ°è¿‡æ—¶ä¿¡æ¯æ•°æ®åŽ»é‡é™åˆ¶æ ‡å‡†çš„ 页é¢ï¼‰å•ä½æ˜¯æ¯«ç§’。较å°çš„毫秒值将以更低的延迟æ¥é‡Šæ”¾KSM元数æ®ï¼Œä½†å®ƒä»¬å°†ä½¿ ksmd在扫æ期间使用更多CPU。如果还没有一个KSM页é¢è¾¾åˆ° ``max_page_sharing`` æ ‡å‡†ï¼Œé‚£å°±æ²¡æœ‰ä»€ä¹ˆç”¨ã€‚ KSM与MADV_MERGEABLE的工作有效性体现于 ``/sys/kernel/mm/ksm/`` 路径下的接å£ï¼š pages_shared 表示多少共享页æ£åœ¨è¢«ä½¿ç”¨ pages_sharing 表示还有多少站点æ£åœ¨å…±äº«è¿™äº›å…±äº«é¡µï¼Œå³èŠ‚çœäº†å¤šå°‘ pages_unshared 表示有多少页是唯一的,但被åå¤æ£€æŸ¥ä»¥è¿›è¡Œåˆå¹¶ pages_volatile è¡¨ç¤ºæœ‰å¤šå°‘é¡µå› å˜åŒ–å¤ªå¿«è€Œæ— æ³•æ”¾åœ¨treeä¸ full_scans 表示所有å¯åˆå¹¶åŒºåŸŸå·²æ‰«æ多少次 stable_node_chains 达到 ``max_page_sharing`` é™åˆ¶çš„KSM页数 stable_node_dups é‡å¤çš„KSM页数 比值 ``pages_sharing/pages_shared`` 的最大值å—é™åˆ¶äºŽ ``max_page_sharing`` 的设定。è¦æƒ³å¢žåŠ 该比值,则相应地è¦å¢žåŠ ``max_page_sharing`` 的值。