.. include:: ../../disclaimer-zh_TW.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`` 的值。 監測KSM的收益 ============= KSMå¯ä»¥é€šéŽåˆä½µç›¸åŒçš„é é¢ä¾†ç¯€çœå…§å˜ï¼Œä½†ä¹Ÿæœƒæ¶ˆè€—é¡å¤–的內å˜ï¼Œå› 爲它需è¦ç”Ÿæˆä¸€äº›rmap_items 來ä¿å˜æ¯å€‹æŽƒæé é¢çš„ç°¡è¦rmapä¿¡æ¯ã€‚其䏿œ‰äº›é é¢å¯èƒ½æœƒè¢«åˆä½µï¼Œä½†æœ‰äº›é é¢åœ¨è¢«æª¢æŸ¥å¹¾æ¬¡ 後å¯èƒ½ç„¡æ³•被åˆä½µï¼Œé€™äº›éƒ½æ˜¯ç„¡ç›Šçš„å…§å˜æ¶ˆè€—。 1) 如何確定KSM在全系統範åœå…§æ˜¯ç¯€çœå…§å˜é‚„是消耗內å˜ï¼Ÿé€™è£æœ‰ä¸€å€‹ç°¡å–®çš„近似計算方法供åƒè€ƒ:: general_profit =~ pages_sharing * sizeof(page) - (all_rmap_items) * sizeof(rmap_item); å…¶ä¸all_rmap_itemså¯ä»¥é€šéŽå° ``pages_sharing`` 〠``pages_shared`` 〠``pages_unshared`` å’Œ ``pages_volatile`` 的求和而輕鬆ç²å¾—。 2) 單一進程ä¸KSM的收益也å¯ä»¥é€šéŽä»¥ä¸‹è¿‘似的計算得到:: process_profit =~ ksm_merging_pages * sizeof(page) - ksm_rmap_items * sizeof(rmap_item). å…¶ä¸ksm_merging_pages顯示在 ``/proc/<pid>/`` 目錄下,而ksm_rmap_items 顯示在 ``/proc/<pid>/ksm_stat`` 。 從應用的角度來看, ``ksm_rmap_items`` å’Œ ``ksm_merging_pages`` çš„é«˜æ¯”ä¾‹æ„ å‘³ç€ä¸å¥½çš„madvise-appliedç–略,所以開發者或管ç†å“¡å¿…é ˆé‡æ–°è€ƒæ…®å¦‚何改變madvisç– ç•¥ã€‚èˆ‰å€‹ä¾‹åä¾›åƒè€ƒï¼Œä¸€å€‹é é¢çš„大å°é€šå¸¸æ˜¯4K,而rmap_item的大å°åœ¨32ä½CPU架構上分 別是32B,在64ä½CPU架構上是64B。所以如果 ``ksm_rmap_items/ksm_merging_pages`` 的比例在64ä½CPU上超éŽ64,或者在32ä½CPU上超éŽ128,那麼應用程åºçš„madviseç–略應 è©²è¢«æ”¾æ£„ï¼Œå› çˆ²ksmæ”¶ç›Šå¤§ç´„çˆ²é›¶æˆ–è² å€¼ã€‚ 監控KSM事件 =========== 在/proc/vmstat䏿œ‰ä¸€äº›è¨ˆæ•¸å™¨ï¼Œå¯ä»¥ç”¨ä¾†ç›£æŽ§KSM事件。KSMå¯èƒ½æœ‰åŠ©æ–¼ç¯€çœå…§å˜ï¼Œé€™æ˜¯ ä¸€ç¨®æ¬Šè¡¡ï¼Œå› çˆ²å®ƒå¯èƒ½æœƒåœ¨KSM COW或複製ä¸çš„交æ›ä¸Šéå—å»¶é²ã€‚這些事件å¯ä»¥å¹«åŠ©ç”¨æˆ¶è©•ä¼° æ˜¯å¦æˆ–如何使用KSM。例如,如果cow_ksmå¢žåŠ å¾—å¤ªå¿«ï¼Œç”¨æˆ¶å¯ä»¥æ¸›å°‘madvise(, , MADV_MERGEABLE) 的範åœã€‚ cow_ksm åœ¨æ¯æ¬¡KSMé é¢è§¸ç™¼å¯«æ™‚æ‹·è²ï¼ˆCOW)時都會被éžå¢žï¼Œç•¶ç”¨æˆ¶è©¦åœ–寫入KSMé 颿™‚, æˆ‘å€‘å¿…é ˆåšä¸€å€‹æ‹·è²ã€‚ ksm_swpin_copy 在æ›å…¥æ™‚ï¼Œæ¯æ¬¡KSMé 被複制時都會被éžå¢žã€‚請注æ„,KSMé 在æ›å…¥æ™‚å¯èƒ½æœƒè¢«è¤‡ åˆ¶ï¼Œå› çˆ²do_swap_page()ä¸èƒ½åšæ‰€æœ‰çš„éŽ–ï¼Œè€Œéœ€è¦é‡çµ„一個跨anon_vmaçš„KSMé 。 -- Izik Eidus, Hugh Dickins, 2009å¹´11月17日。