:Original: Documentation/mm/page_owner.rst :翻译: å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn> :æ ¡è¯‘: ================================ page owner: 跟踪è°åˆ†é…çš„æ¯ä¸ªé¡µé¢ ================================ 概述 ==== page owner是用æ¥è¿½è¸ªè°åˆ†é…çš„æ¯ä¸€ä¸ªé¡µé¢ã€‚它å¯ä»¥ç”¨æ¥è°ƒè¯•å†…å˜æ³„æ¼æˆ–找到内å˜å 用者。 当分é…å‘生时,有关分é…çš„ä¿¡æ¯ï¼Œå¦‚è°ƒç”¨å †æ ˆå’Œé¡µé¢çš„顺åºè¢«å˜å‚¨åˆ°æ¯ä¸ªé¡µé¢çš„特定å˜å‚¨ä¸ã€‚ 当我们需è¦äº†è§£æ‰€æœ‰é¡µé¢çš„状æ€æ—¶ï¼Œæˆ‘们å¯ä»¥èŽ·å¾—并分æžè¿™äº›ä¿¡æ¯ã€‚ 尽管我们已ç»æœ‰äº†è¿½è¸ªé¡µé¢åˆ†é…/释放的tracepoint,但用它æ¥åˆ†æžè°åˆ†é…çš„æ¯ä¸ªé¡µé¢æ˜¯ 相当å¤æ‚的。我们需è¦æ‰©å¤§è·Ÿè¸ªç¼“冲区,以防æ¢åœ¨ç”¨æˆ·ç©ºé—´ç¨‹åºå¯åŠ¨å‰å‡ºçŽ°é‡å ã€‚è€Œä¸”ï¼Œå¯ åŠ¨çš„ç¨‹åºä¼šä¸æ–地将跟踪缓冲区转出,供以åŽåˆ†æžï¼Œè¿™å°†ä¼šæ”¹å˜ç³»ç»Ÿçš„行为,会产生更多的 å¯èƒ½æ€§ï¼Œè€Œä¸æ˜¯ä»…ä»…ä¿ç•™åœ¨å†…å˜ä¸ï¼Œæ‰€ä»¥ä¸åˆ©äºŽè°ƒè¯•ã€‚ 页é¢æ‰€æœ‰è€…也å¯ä»¥ç”¨äºŽå„ç§ç›®çš„。例如,å¯ä»¥é€šè¿‡æ¯ä¸ªé¡µé¢çš„gfpæ ‡å¿—ä¿¡æ¯èŽ·å¾—精确的碎片 统计。如果å¯ç”¨äº†page owner,它就已ç»å®žçŽ°å¹¶æ¿€æ´»äº†ã€‚我们éžå¸¸æ¬¢è¿Žå…¶ä»–用途。 page owner在默认情况下是ç¦ç”¨çš„ã€‚æ‰€ä»¥ï¼Œå¦‚æžœä½ æƒ³ä½¿ç”¨å®ƒï¼Œä½ éœ€è¦åœ¨ä½ çš„å¯åŠ¨cmdline ä¸åŠ å…¥"page_owner=on"ã€‚å¦‚æžœå†…æ ¸æ˜¯ç”¨page owner构建的,并且由于没有å¯ç”¨å¯åŠ¨ 选项而在è¿è¡Œæ—¶ç¦ç”¨page owner,那么è¿è¡Œæ—¶çš„开销是很å°çš„。如果在è¿è¡Œæ—¶ç¦ç”¨ï¼Œå®ƒä¸ 需è¦å†…å˜æ¥å˜å‚¨æ‰€æœ‰è€…ä¿¡æ¯ï¼Œæ‰€ä»¥æ²¡æœ‰è¿è¡Œæ—¶å†…å˜å¼€é”€ã€‚而且,页é¢æ‰€æœ‰è€…在页é¢åˆ†é…器的 çƒè·¯å¾„ä¸åªæ’入了两个ä¸å¯èƒ½çš„分支,如果ä¸å¯ç”¨ï¼Œé‚£ä¹ˆåˆ†é…就会åƒæ²¡æœ‰é¡µé¢æ‰€æœ‰è€…çš„å†…æ ¸ ä¸€æ ·è¿›è¡Œã€‚è¿™ä¸¤ä¸ªä¸å¯èƒ½çš„分支应该ä¸ä¼šå½±å“到分é…的性能,特别是在é™æ€é”®è·³è½¬æ ‡ç¾ä¿®è¡¥ 功能å¯ç”¨çš„æƒ…å†µä¸‹ã€‚ä»¥ä¸‹æ˜¯ç”±äºŽè¿™ä¸ªåŠŸèƒ½è€Œå¯¼è‡´çš„å†…æ ¸ä»£ç 大å°çš„å˜åŒ–。 尽管å¯ç”¨page ownerä¼šä½¿å†…æ ¸çš„å¤§å°å¢žåŠ å‡ åƒå—节,但这些代ç 大部分都在页é¢åˆ†é…器和 çƒè·¯å¾„之外。构建带有page ownerçš„å†…æ ¸ï¼Œå¹¶åœ¨éœ€è¦æ—¶æ‰“å¼€å®ƒï¼Œå°†æ˜¯è°ƒè¯•å†…æ ¸å†…å˜é—®é¢˜çš„ 最佳选择。 有一个问题是由实现细节引起的。页所有者将信æ¯å˜å‚¨åˆ°struct page扩展的内å˜ä¸ã€‚è¿™ 个内å˜çš„åˆå§‹åŒ–时间比稀ç–内å˜ç³»ç»Ÿä¸çš„页é¢åˆ†é…器å¯åŠ¨çš„时间è¦æ™šä¸€äº›ï¼Œæ‰€ä»¥ï¼Œåœ¨åˆå§‹åŒ– 之å‰ï¼Œè®¸å¤šé¡µé¢å¯ä»¥è¢«åˆ†é…,但它们没有所有者信æ¯ã€‚为了解决这个问题,这些早期分é…çš„ 页é¢åœ¨åˆå§‹åŒ–é˜¶æ®µè¢«è°ƒæŸ¥å¹¶æ ‡è®°ä¸ºåˆ†é…。虽然这并ä¸æ„味ç€å®ƒä»¬æœ‰æ£ç¡®çš„所有者信æ¯ï¼Œä½†è‡³ 少,我们å¯ä»¥æ›´å‡†ç¡®åœ°åˆ¤æ–该页是å¦è¢«åˆ†é…。在2GB内å˜çš„x86-64虚拟机上,有13343 个早期分é…的页é¢è¢«æ•æ‰å’Œæ ‡è®°ï¼Œå°½ç®¡å®ƒä»¬å¤§éƒ¨åˆ†æ˜¯ç”±ç»“构页扩展功能分é…的。总之,在这 之åŽï¼Œæ²¡æœ‰ä»»ä½•é¡µé¢å¤„于未追踪状æ€ã€‚ 使用方法 ======== 1) 构建用户空间的帮助:: cd tools/mm make page_owner_sort 2) å¯ç”¨page owner: æ·»åŠ "page_owner=on" 到 boot cmdline. 3) åšä½ 想调试的工作。 4) 分æžæ¥è‡ªé¡µé¢æ‰€æœ‰è€…çš„ä¿¡æ¯:: cat /sys/kernel/debug/page_owner > page_owner_full.txt ./page_owner_sort page_owner_full.txt sorted_page_owner.txt ``page_owner_full.txt`` 的一般输出情况如下:: Page allocated via order XXX, ... PFN XXX ... // æ ˆè¯¦æƒ… Page allocated via order XXX, ... PFN XXX ... // æ ˆè¯¦æƒ… 默认情况下,它将以一个给定的pfn开始,åšå®Œæ•´çš„pfn转储,且page_owner支æŒfseek。 FILE *fp = fopen("/sys/kernel/debug/page_owner", "r"); fseek(fp, pfn_start, SEEK_SET); ``page_owner_sort`` 工具忽略了 ``PFN`` 行,将剩余的行放在bufä¸ï¼Œä½¿ç”¨regexpæ å–页åºå€¼ï¼Œè®¡ç®—buf的次数和页数,最åŽæ ¹æ®å‚数进行排åºã€‚ 在 ``sorted_page_owner.txt`` ä¸å¯ä»¥çœ‹åˆ°å…³äºŽè°åˆ†é…了æ¯ä¸ªé¡µé¢çš„结果。一般输出:: XXX times, XXX pages: Page allocated via order XXX, ... // Detailed stack 默认情况下, ``page_owner_sort`` æ˜¯æ ¹æ®buf的时间æ¥æŽ’åºçš„ã€‚å¦‚æžœä½ æƒ³ 按buf的页数排åºï¼Œè¯·ä½¿ç”¨-må‚数。详细的å‚数是: 基本函数:: 排åº: -a 按内å˜åˆ†é…æ—¶é—´æŽ’åº -m 按总内å˜æŽ’åº -p 按pid排åºã€‚ -P 按tgid排åºã€‚ -n 按任务命令å称排åºã€‚ -r 按内å˜é‡Šæ”¾æ—¶é—´æŽ’åºã€‚ -s æŒ‰å †æ ˆè·Ÿè¸ªæŽ’åºã€‚ -t 按时间排åºï¼ˆé»˜è®¤ï¼‰ã€‚ --sort <order> 指定排åºé¡ºåºã€‚排åºçš„è¯æ³•æ˜¯[+|-]key[,[+|-]key[,...]]。从 **æ ‡å‡†æ ¼å¼æŒ‡å®šå™¨**那一节选择一个键。"+"是å¯é€‰çš„ï¼Œå› ä¸ºé»˜è®¤çš„æ–¹å‘是数å—或 è¯æ³•çš„å¢žåŠ ã€‚å…许混åˆä½¿ç”¨ç¼©å†™å’Œå®Œæ•´æ ¼å¼çš„键。 例å: ./page_owner_sort <input> <output> --sort=n,+pid,-tgid ./page_owner_sort <input> <output> --sort=at 其它函数:: 剔除: --cull <rules> 指定剔除规则。剔除的è¯æ³•æ˜¯key[,key[,...]]。从**æ ‡å‡†æ ¼å¼æŒ‡å®šå™¨** 部分选择一个多å—æ¯é”®ã€‚ <rules>是一个以逗å·åˆ†éš”的列表形å¼çš„å•ä¸€å‚数,它æ供了一ç§æŒ‡å®šå•ä¸ªå‰”除规则的 方法。 识别的关键å—在下é¢çš„**æ ‡å‡†æ ¼å¼æŒ‡å®šå™¨**部分有æ述。<规则>å¯ä»¥é€šè¿‡é”®çš„ åºåˆ—k1,k2,...æ¥æŒ‡å®šï¼Œåœ¨ä¸‹é¢çš„æ ‡å‡†æŽ’åºé”®éƒ¨åˆ†æœ‰æ述。å…许混åˆä½¿ç”¨ç®€å†™å’Œå®Œæ•´å½¢ å¼çš„键。 Examples: ./page_owner_sort <input> <output> --cull=stacktrace ./page_owner_sort <input> <output> --cull=st,pid,name ./page_owner_sort <input> <output> --cull=n,f 过滤: -f 过滤掉内å˜å·²è¢«é‡Šæ”¾çš„å—çš„ä¿¡æ¯ã€‚ 选择: --pid <pidlist> 按pid选择。这将选择进程IDå·å‡ºçŽ°åœ¨<pidlist>ä¸çš„å—。 --tgid <tgidlist> 按tgid选择。这将选择其线程组IDå·å‡ºçŽ°åœ¨<tgidlist> ä¸çš„å—。 --name <cmdlist> 按任务命令å称选择。这将选择其任务命令å称出现在 <cmdlist>ä¸çš„区å—。 <pidlist>, <tgidlist>, <cmdlist>是以逗å·åˆ†éš”的列表形å¼çš„å•ä¸ªå‚数, 它æ供了一ç§æŒ‡å®šå•ä¸ªé€‰æ‹©è§„则的方法。 例å: ./page_owner_sort <input> <output> --pid=1 ./page_owner_sort <input> <output> --tgid=1,2,3 ./page_owner_sort <input> <output> --name name1,name2 æ ‡å‡†æ ¼å¼æŒ‡å®šå™¨ ============== :: --sort的选项: çŸé”® é•¿é”® æè¿° p pid 进程ID tg tgid 线程组ID n name 任务命令å称 st stacktrace 页é¢åˆ†é…çš„å †æ ˆè·Ÿè¸ª T txt å—的全文 ft free_ts 页é¢é‡Šæ”¾æ—¶çš„时间戳 at alloc_ts 页é¢è¢«åˆ†é…时的时间戳 ator allocator 页é¢çš„内å˜åˆ†é…器 --curl的选项: çŸé”® é•¿é”® æè¿° p pid 进程ID tg tgid 线程组ID n name 任务命令å称 f free 该页是å¦å·²ç»é‡Šæ”¾ st stacktrace 页é¢åˆ†é…çš„å †æ ˆè·Ÿè¸ª ator allocator 页é¢çš„内å˜åˆ†é…器