詳細(xì)講解Linux內(nèi)存管理之RMAP
說(shuō)明:
Kernel版本:4.14
ARM64處理器,Contex-A53,雙核
使用工具:Source Insight 3.5, Visio
1. 概述
RMAP反向映射是一種物理地址反向映射虛擬地址的方法。
映射 頁(yè)表用于虛擬地址到物理地址映射,其中的PTE頁(yè)表項(xiàng)記錄了映射關(guān)系,同時(shí)struct page結(jié)構(gòu)體中的mapcount字段保存了有多少PTE頁(yè)表項(xiàng)映射了該物理頁(yè)。
反向映射 當(dāng)某個(gè)物理地址要進(jìn)行回收或遷移時(shí),此時(shí)需要去找到有多少虛擬地址射在該物理地址,并斷開映射處理。在沒有反向映射的機(jī)制時(shí),需要去遍歷進(jìn)程的頁(yè)表,這個(gè)效率顯然是很低下的。反向映射可以找到虛擬地址空間VMA,并僅從VMA使用的用戶頁(yè)表中取消映射,可以快速解決這個(gè)問(wèn)題。

反向映射的典型應(yīng)用場(chǎng)景:
kswapd進(jìn)行頁(yè)面回收時(shí),需要斷開所有映射了該匿名頁(yè)面的PTE表項(xiàng);
頁(yè)面遷移時(shí),需要斷開所有映射了該匿名頁(yè)面的PTE表項(xiàng);
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!?。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ? ?


2. 數(shù)據(jù)結(jié)構(gòu)
反向映射有三個(gè)關(guān)鍵的結(jié)構(gòu)體:
struct vm_area_struct,簡(jiǎn)稱VMA;VMA我們?cè)谥暗奈恼轮薪榻B過(guò),用于描述進(jìn)程地址空間中的一段區(qū)域。與反向映射相關(guān)的字段如下:
2.struct anon_vma
,簡(jiǎn)稱AV
;AV
結(jié)構(gòu)用于管理匿名類型VMAs
,當(dāng)有匿名頁(yè)需要unmap
處理時(shí),可以先找到AV
,然后再通過(guò)AV
進(jìn)行查找處理。結(jié)構(gòu)如下:
3.struct anon_vma_chain
,簡(jiǎn)稱AVC
;AVC
是連接VMA
和AV
之間的橋梁。
來(lái)一張圖就清晰明了了:

通過(guò)
same_vma
鏈表節(jié)點(diǎn),將anon_vma_chain
添加到vma->anon_vma_chain
鏈表中;通過(guò)
rb
紅黑樹節(jié)點(diǎn),將anon_vma_chain
添加到anon_vma->rb_root
的紅黑樹中;
2. 流程分析
先看一下宏觀的圖:

地址空間
VMA
可以通過(guò)頁(yè)表完成虛擬地址到物理地址的映射;頁(yè)框與
page
結(jié)構(gòu)對(duì)應(yīng),page
結(jié)構(gòu)中的mapping
字段指向anon_vma
,從而可以通過(guò)RMAP
機(jī)制去找到與之關(guān)聯(lián)的VMA
;
2.1?anon_vma_prepare
之前在page fault
的文章中,提到過(guò)anon_vma_prepare
函數(shù),這個(gè)函數(shù)完成的工作就是為進(jìn)程地址空間中的VMA
準(zhǔn)備struct anon_vma
結(jié)構(gòu)。
調(diào)用例程及函數(shù)流程如下圖所示:

至于VMA,AV,AVC
三者之間的關(guān)聯(lián)關(guān)系,在上文的圖中已經(jīng)有所描述。
當(dāng)創(chuàng)建了與VMA
關(guān)聯(lián)的AV
后,還有關(guān)鍵的一步需要做完,才能算是真正的把RMAP
通路打通,那就是讓page
與AV
關(guān)聯(lián)起來(lái)。只有這樣才能通過(guò)page
找到AV
,進(jìn)而找到VMA
,從而完成對(duì)應(yīng)的PTE unmmap
操作。

2.2 子進(jìn)程創(chuàng)建anon_vma
父進(jìn)程通過(guò)fork()
來(lái)創(chuàng)建子進(jìn)程,子進(jìn)程會(huì)復(fù)制整個(gè)父進(jìn)程的地址空間及頁(yè)表。子進(jìn)程拷貝了父進(jìn)程的VMA
數(shù)據(jù)結(jié)構(gòu)內(nèi)容,而子進(jìn)程創(chuàng)建相應(yīng)的anon_vma
結(jié)構(gòu),是通過(guò)anon_vma_fork()
函數(shù)來(lái)實(shí)現(xiàn)的。
anon_vma_fork()
效果圖如下:

以實(shí)際fork()
兩次為例,發(fā)生COW
之后,看看三個(gè)進(jìn)程的鏈接關(guān)系,如下圖:

2.3?TTU(try to unmap)
和Rmap Walk
如果有page
被映射到多個(gè)虛擬地址,可以通過(guò)Rmap Walk機(jī)制
來(lái)遍歷所有的VMA
,并最終調(diào)用回調(diào)函數(shù)來(lái)取消映射。
與之相關(guān)的結(jié)構(gòu)體為struct rmap_walk_control
,如下:

取消映射的入口為try_to_unmap
,流程如下圖所示:

基本的套路就是圍繞著struct rmap_walk_control
結(jié)構(gòu),初始化回調(diào)函數(shù),以便在適當(dāng)?shù)臅r(shí)候能調(diào)用到。
關(guān)于取消映射try_to_unmap_one
的詳細(xì)細(xì)節(jié)就不進(jìn)一步深入了,把握好大體框架即可。
原文作者:LoyenWang
