五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

深入解決Linux內(nèi)存管理之page fault處理

2022-12-12 20:37 作者:補給站Linux內(nèi)核  | 我要投稿

說明:

  1. Kernel版本:4.14

  2. ARM64處理器,Contex-A53,雙核

  3. 使用工具:Source Insight 3.5, Visio

1. 概述

上篇文章分析到malloc/mmap函數(shù)中,內(nèi)核實現(xiàn)只是在進程的地址空間建立好了vma區(qū)域,并沒有實際的虛擬地址到物理地址的映射操作。這部分就是在Page Fault異常錯誤處理中實現(xiàn)的。

Linux內(nèi)核中的Page Fault異常處理很復(fù)雜,涉及的細節(jié)也很多,malloc/mmap的物理內(nèi)存映射只是它的一個子集功能,下圖大概涵蓋了出現(xiàn)Page Fault的情況:

圖片

下邊就開始來啃啃硬骨頭吧。


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ? ?

2. Arm64處理

Page Fault的異常處理,依賴于體系結(jié)構(gòu),因此有必要來介紹一下Arm64的處理。代碼主要參考:arch/arm64/kernel/entry.S。

圖片

Arm64在取指令或者訪問數(shù)據(jù)時,需要把虛擬地址轉(zhuǎn)換成物理地址,這個過程需要進行幾種檢查,在不滿足的情況下都能造成異常:

  1. 地址的合法性,比如以39有效位地址為例,內(nèi)核地址的高25位為全1,用戶進程地址的高25位為全0;

  2. 地址的權(quán)限檢查,這里邊的權(quán)限位都位于頁表條目中;

從上圖中可以看到,最后都會調(diào)到do_mem_abort函數(shù),這個函數(shù)比較簡單,直接看代碼,位于arch/arm64/mm/fault.c

該函數(shù)中關(guān)鍵的處理:根據(jù)傳進來的esr獲取fault_info信息,從而去調(diào)用函數(shù)。struct fault_info用于錯誤狀態(tài)下對應(yīng)的處理方法,而內(nèi)核中也定義了全局結(jié)構(gòu)fault_info,存放了所有的情況。主要的錯誤狀態(tài)和處理函數(shù)對應(yīng)如下:

從代碼中可以看出:

  • 出現(xiàn)0/1/2/3級頁表轉(zhuǎn)換錯誤時,會調(diào)用do_translation_fault,實際中do_translation_fault最終也會調(diào)用到do_page_fault;

  • 出現(xiàn)1/2/3級頁表訪問權(quán)限的時候,會調(diào)用do_page_fault;

  • 其他的錯誤則調(diào)用do_bad,其中未列出來的部分還包括do_sea等操作函數(shù);


do_translation_fault

圖片


do_page_fault

圖片

do_page_fault函數(shù)為頁錯誤異常處理的核心函數(shù),與體系結(jié)構(gòu)相關(guān),上圖中的handle_mm_fault函數(shù)為通用函數(shù),也就是不管哪種處理器結(jié)構(gòu),最終都會調(diào)用到該函數(shù)。

3.?handle_mm_fault

handle_mm_fault用于處理用戶空間的頁錯誤異常:

  • 進程在用戶模式下訪問用戶虛擬地址,觸發(fā)頁錯誤異常;

  • 進程在內(nèi)核模式下訪問用戶虛擬地址,觸發(fā)頁錯誤異常;從do_page_fault函數(shù)的流程圖中也能看出來,當觸發(fā)異常的虛擬地址屬于某個vma,并且擁有觸發(fā)頁錯誤異常的權(quán)限時,會調(diào)用到handle_mm_fault函數(shù),而handle_mm_fault函數(shù)的主要邏輯是通過__handle_mm_fault來實現(xiàn)的。

流程如下圖:

圖片

3.1?do_fault

do_fault函數(shù)用于處理文件頁異常,包括以下三種情況:

  1. 讀文件頁錯誤;

  2. 寫私有文件頁錯誤;

  3. 寫共享文件頁錯誤;

圖片

3.2?do_anonymous_page

匿名頁的缺頁異常處理調(diào)用本函數(shù),在以下情況下會觸發(fā):

  1. malloc/mmap分配了進程地址空間區(qū)域,但是沒有進行映射處理,在首次訪問時觸發(fā);

  2. 用戶棧不夠的情況下,進行棧區(qū)的擴大處理;

圖片

3.3?do_swap_page

如果訪問Swap頁面出錯(頁面不在內(nèi)存中),則從Swap cacheSwap文件中讀取該頁面。由于在4.14內(nèi)核版本中,do_swap_page調(diào)用的很多函數(shù)都是空函數(shù),無法進一步的了解,大體的流程如下圖:

圖片

3.4?do_wp_page

do_wp_page函數(shù)用于處理寫時復(fù)制(copy on write),會在以下兩種情況處理:

  1. 創(chuàng)建子進程時,父子進程會以只讀方式共享私有的匿名頁和文件頁,當試圖寫的時候,觸發(fā)頁錯誤異常,從而復(fù)制物理頁,并創(chuàng)建映射;

  2. 進程創(chuàng)建私有文件映射,讀訪問后觸發(fā)異常,將文件頁讀入到page cache中,并以只讀模式創(chuàng)建映射,之后發(fā)生寫訪問后,觸發(fā)COW

圖片

關(guān)鍵的復(fù)制工作是由wp_page_copy完成的:

圖片

原文作者:LoyenWang



深入解決Linux內(nèi)存管理之page fault處理的評論 (共 條)

分享到微博請遵守國家法律
祁东县| 嫩江县| 西和县| 铁力市| 德阳市| 抚顺市| 宾阳县| 揭东县| 郎溪县| 宕昌县| 吉隆县| 于都县| 德州市| 正镶白旗| 通州市| 大埔区| 长沙县| 墨玉县| 马尔康县| 团风县| 灵石县| 嘉善县| 成武县| 秭归县| 罗源县| 阳东县| 宁晋县| 永仁县| 南平市| 聊城市| 莒南县| 宜宾县| 孙吴县| 南川市| 岑溪市| 柳江县| 五原县| 唐河县| 广东省| 永泰县| 宿迁市|