本發(fā)明屬于通信技術(shù)領(lǐng)域,具體涉及一種基于linux大頁內(nèi)存的易擴(kuò)展頁面架構(gòu)。
背景技術(shù):
內(nèi)存管理是linux內(nèi)核中最重要的一部分。內(nèi)存采用“分頁機(jī)制”,用于支持對(duì)大地址空間的快速、高效的管理。雖然原則上內(nèi)存頁面大小是可配置的,但linux內(nèi)核中采用默認(rèn)的4kb(4096字節(jié))頁面,即小頁。當(dāng)linux操作系統(tǒng)上運(yùn)行內(nèi)存需求量較大的應(yīng)用程序時(shí),由于其采用的默認(rèn)頁面大小為4kb,因而會(huì)產(chǎn)生較多tlbmiss和缺頁中斷,從而大大影響應(yīng)用程序的性能,因此,linux內(nèi)核中也引入大頁面支持。當(dāng)操作系統(tǒng)以2mb甚至更大作為分頁的單位時(shí),這大大減少tlbmiss和缺頁中斷的數(shù)量,顯著提高應(yīng)用程序的性能。
為了能以最小的代價(jià)實(shí)現(xiàn)大頁面支持,linux操作系統(tǒng)采用了基于hugetlbfs特殊文件系統(tǒng)2m字節(jié)大頁面支持。這種采用特殊文件系統(tǒng)形式支持大頁面的方式,使得應(yīng)用程序可以根據(jù)需要靈活地選擇虛存頁面大小。但是,從本質(zhì)上講hugetlbfs的實(shí)現(xiàn)方式僅僅是一個(gè)通過“打補(bǔ)丁”的手段來支持靈活的內(nèi)存頁面大小,受限于linux內(nèi)核。大頁文件系統(tǒng)與小頁仍共用伙伴系統(tǒng),這使得在大頁上的開發(fā)設(shè)計(jì)時(shí),難免會(huì)影響到小頁,不利于進(jìn)一步的開發(fā)和擴(kuò)展。
技術(shù)實(shí)現(xiàn)要素:
鑒于上述,本發(fā)明提供了一種基于linux大頁內(nèi)存的易擴(kuò)展頁面架構(gòu),該架構(gòu)不再與小頁文件系統(tǒng)共用伙伴系統(tǒng),被單獨(dú)管理,且能夠與linux內(nèi)核進(jìn)行解耦,提升內(nèi)存存儲(chǔ)調(diào)用的獨(dú)立性。
一種基于linux大頁內(nèi)存的易擴(kuò)展頁面架構(gòu),包括:大頁內(nèi)存及調(diào)用大頁內(nèi)存的接口函數(shù),所述的大頁內(nèi)存分為多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)分為多個(gè)分區(qū),每個(gè)分區(qū)由以雙向鏈表的形式連接在一起的多個(gè)2m大頁組成,所述的接口函數(shù)包括用于獲取單個(gè)大頁的申請(qǐng)函數(shù)、用于釋放大頁的釋放函數(shù)、用于將大頁占為己有且禁止其他進(jìn)程訪問的鎖函數(shù)以及用于恢復(fù)大頁自由的解鎖函數(shù)。
所述的每個(gè)大頁包含以下幾個(gè)條目:
flags:用于標(biāo)記頁面的屬性,且其中包含如下標(biāo)志位:
pg_locked,當(dāng)頁被一個(gè)進(jìn)程訪問時(shí),該位置1,其他進(jìn)程等待;
pg_dirty,當(dāng)頁中的內(nèi)容被修改后,該位置1,表示數(shù)據(jù)要寫回;
pg_private,該位為1表示頁不能被共享,為0可以被共享;
pg_referenced,pg_active,兩個(gè)標(biāo)志位共同來記錄一個(gè)頁的訪問活躍程度,用在冷熱頁調(diào)度中,兩個(gè)位都為1時(shí)進(jìn)入熱頁池,都為0時(shí)進(jìn)入冷頁池,其他情況不移動(dòng);
mapping:用來指引正在映射的索引節(jié)點(diǎn)inode;
index:表示在映射表中的偏移;
lru:用于每個(gè)分區(qū)的大頁雙向鏈表構(gòu)建,大頁鏈表順序按照最近最少使用算法,故叫做lru,這里lru指向前大頁的lrui-1和后大頁的lrui+1;
mapcount:用于記錄頁共享者的個(gè)數(shù)。
所述的申請(qǐng)函數(shù)實(shí)現(xiàn)從大頁內(nèi)存中獲取單個(gè)大頁,具體過程為:
(a-1)查詢linux系統(tǒng)中的node_possible_map,獲取節(jié)點(diǎn)分布,判斷節(jié)點(diǎn)的個(gè)數(shù)以及節(jié)點(diǎn)是否含有內(nèi)存空間,并從第一個(gè)含有內(nèi)存空間的節(jié)點(diǎn)進(jìn)行查詢;
(a-2)獲取當(dāng)前節(jié)點(diǎn)的分區(qū)分布,判斷當(dāng)前節(jié)點(diǎn)是否含有分區(qū),若是,執(zhí)行步驟(a-3),若否,結(jié)束該節(jié)點(diǎn)的查詢,并執(zhí)行步驟(a-7);
(a-3)查找當(dāng)前節(jié)點(diǎn)的第一分區(qū),并判斷當(dāng)前分區(qū)中是否空閑大頁,若是,執(zhí)行步驟(a-6),若否,執(zhí)行步驟(a-4);
(a-4)判斷當(dāng)前節(jié)點(diǎn)的下一個(gè)分區(qū)中是否含有空閑大頁,若是,執(zhí)行步驟(a-6),若否,執(zhí)行步驟(a-5);
(a-5)重復(fù)循環(huán)步驟(a-4),直到遍歷當(dāng)前節(jié)點(diǎn)的所有分區(qū)為止,若當(dāng)前節(jié)點(diǎn)的最后一個(gè)分區(qū)不含有空閑大頁,執(zhí)行步驟(a-7)。
(a-6)將空閑大頁的共享計(jì)數(shù)mapcount設(shè)為1,并將該大頁從當(dāng)前分區(qū)的活動(dòng)鏈表上去除,調(diào)整該分區(qū)中前后大頁的lru1、lru2,使lru1指向后大頁,lru2指向前大頁,返回獲取的大頁,結(jié)束函數(shù);
(a-7)將下一個(gè)節(jié)點(diǎn)作為當(dāng)前節(jié)點(diǎn),執(zhí)行步驟(a-2),直到遍歷所有含有內(nèi)存空間的節(jié)點(diǎn),若遍歷到最后一個(gè)含有內(nèi)存空間的節(jié)點(diǎn)中的最后一個(gè)分區(qū)的所有大頁,未找到空閑大頁,則獲取大頁失敗。
所述的釋放函數(shù)實(shí)現(xiàn)將不使用的大頁釋放到大頁內(nèi)存中,具體過程為:
(b-1)判斷當(dāng)前大頁的共享計(jì)數(shù)mapcount是否為1,若是,執(zhí)行步驟(b-2),若否,將共享計(jì)數(shù)mapcount減1,結(jié)束大頁釋放;
(b-2)判斷是否能夠獲取當(dāng)前大頁所在的節(jié)點(diǎn)及分區(qū)信息,若是,執(zhí)行步驟(b-3),若否,執(zhí)行報(bào)錯(cuò);
(b-3)根據(jù)獲取的當(dāng)前大頁所在的節(jié)點(diǎn)及分區(qū)信息,將該大頁添加至其所在分區(qū)的大頁鏈表上,調(diào)整該大頁的lru1,使lru指向正確的前后大頁,調(diào)整前后大頁的lru2、lru3,使lru2、lru3指向該大頁,并將該大頁所屬的分區(qū)的空間大頁數(shù)目加1,將該大頁所屬的節(jié)點(diǎn)的空閑大頁數(shù)目加1,將該大頁的共享計(jì)數(shù)mapcount設(shè)為0,大頁釋放完成。
所述的鎖函數(shù)實(shí)現(xiàn)將大頁占為己有,禁止其他進(jìn)程訪問,具體過程為:
(c-1)查看當(dāng)前大頁的標(biāo)志flags,判斷當(dāng)前大頁的屬性是否為禁止鎖,若是,退出查看,若否,執(zhí)行步驟(c-2);
(c-2)繼續(xù)查看當(dāng)前大頁的標(biāo)志flags,判斷當(dāng)前大頁是否已經(jīng)被鎖,若是,執(zhí)行步驟(c-3),若否,執(zhí)行步驟(c-4);
(c-3)將當(dāng)前進(jìn)程添加到該大頁所屬節(jié)點(diǎn)的一個(gè)等待隊(duì)列中;
(c-4)將大頁標(biāo)志里flags中的pg_locked設(shè)為1,完成該大頁的上鎖。
所述的解鎖函數(shù)實(shí)現(xiàn)恢復(fù)大頁自由,可以被其他進(jìn)程訪問,具體過程為:
修改大頁的標(biāo)志flags,將標(biāo)志flags中的pg_locked設(shè)為0,表示該大頁可以被其他進(jìn)程訪問。由于大頁被鎖,之前的所有請(qǐng)求該大頁是進(jìn)程都被添加到該大頁所屬的節(jié)點(diǎn)中的等待隊(duì)列中,此時(shí)大頁被解鎖,將重新喚醒節(jié)點(diǎn)中等待隊(duì)列的進(jìn)程,讓其繼續(xù)運(yùn)行。
本發(fā)明在linux的內(nèi)存管理中,實(shí)現(xiàn)了一套易拓展的大頁構(gòu)架。該大頁構(gòu)架拋棄了原有的伙伴系統(tǒng)機(jī)制,與小頁之間進(jìn)行切割,單獨(dú)成塊。同時(shí),大頁構(gòu)建也實(shí)現(xiàn)了構(gòu)架本身的結(jié)構(gòu)定義、接口函數(shù)的定義。本發(fā)明的大頁構(gòu)架不會(huì)牽涉到原有小頁的功能和實(shí)現(xiàn),可以方便進(jìn)行大頁的壓縮、遷移等開發(fā)。
附圖說明
圖1為本發(fā)明實(shí)施例大頁內(nèi)存的組織方式的示意圖;
圖2為本發(fā)明實(shí)施例大頁架構(gòu)與上層接口示意圖。
具體實(shí)施方式
為了更為具體地描述本發(fā)明,下面結(jié)合附圖及具體實(shí)施方式對(duì)本發(fā)明的技術(shù)方案進(jìn)行詳細(xì)說明。
本發(fā)明以linux系統(tǒng)的內(nèi)存管理為基礎(chǔ),并根據(jù)內(nèi)核中的“分頁機(jī)制”下的大頁模式。通過簡(jiǎn)化,實(shí)現(xiàn)了一種基于linux內(nèi)存管理的非伙伴系統(tǒng)大頁架構(gòu)。在內(nèi)核中的組織方式,與原有大頁架構(gòu)完全不同。
如圖1所示的是本實(shí)施例大頁內(nèi)存采用的組織方式。在numa體系的計(jì)算機(jī)中,大頁內(nèi)存分為3個(gè)節(jié)點(diǎn)node,每個(gè)節(jié)點(diǎn)的內(nèi)存分為3個(gè)分區(qū)section,考慮性能方面的原因,分區(qū)的大小設(shè)為1g;每個(gè)分區(qū)由以雙向鏈表的形式連接在一起的3個(gè)2m大頁hugepage。
實(shí)際應(yīng)用時(shí),大頁內(nèi)存可劃分為任意個(gè)節(jié)點(diǎn),且每個(gè)節(jié)點(diǎn)可劃分為任意個(gè)分區(qū)。每個(gè)分區(qū)中都會(huì)建立一個(gè)雙向鏈表,每個(gè)大頁中的lru項(xiàng),用來記錄該大頁的后一個(gè)大頁和前一大頁。
大頁是大頁內(nèi)存中的基本單元,其中含有一些元數(shù)據(jù),來記錄本大頁的信息。這些信息會(huì)在調(diào)用時(shí)使用,幫助大頁的組織和管理。具體分為下面幾個(gè)條目:
flags:用于標(biāo)記頁面的屬性,flags中包含如下標(biāo)志位:
pg_locked,當(dāng)頁被一個(gè)進(jìn)程訪問時(shí),該位置1,其他進(jìn)程等待;
pg_dirty,當(dāng)頁中的內(nèi)容被修改后,該位置1,表示數(shù)據(jù)要寫回;
pg_private,該位為1表示頁不能被共享,為0可以被共享;
pg_referenced,pg_active,兩個(gè)標(biāo)志位共同來記錄一個(gè)頁的訪問活躍程度,用在冷熱頁調(diào)度中,兩個(gè)位都為1時(shí)進(jìn)入熱頁池,都為0時(shí)進(jìn)入冷頁池,其他情況不移動(dòng)。
mapping:用來指引正在映射的索引節(jié)點(diǎn)inode;
index:表示在映射表中的偏移;
lru:用于每個(gè)分區(qū)的大頁雙向鏈表構(gòu)建(大頁鏈表順序按照最近最少使用算法,故叫做lru),這里lru指向前后大頁的lrui-1、lrui+1;
mapcount:用于記錄頁共享者的個(gè)數(shù)。
如圖2所示,本實(shí)施例還提供了四個(gè)用于本大頁內(nèi)存的四個(gè)接口函數(shù),具體包括:申請(qǐng)函數(shù)alloc_page、釋放函數(shù)free_page、鎖函數(shù)lock_page以及解鎖函數(shù)unlock_page。
申請(qǐng)函數(shù)alloc_page用于從大頁內(nèi)存中獲取單個(gè)大頁,具體實(shí)現(xiàn)過程為:
(a-1)查詢linux系統(tǒng)中的node_possible_map,獲取節(jié)點(diǎn)分布,判斷節(jié)點(diǎn)的個(gè)數(shù)以及節(jié)點(diǎn)是否含有內(nèi)存空間,并從第一個(gè)含有內(nèi)存空間的節(jié)點(diǎn)進(jìn)行查詢;
(a-2)獲取當(dāng)前節(jié)點(diǎn)的分區(qū)分布,判斷當(dāng)前節(jié)點(diǎn)是否含有分區(qū),若是,執(zhí)行步驟(a-3),若否,結(jié)束該節(jié)點(diǎn)的查詢,并執(zhí)行步驟(a-7);
(a-3)查找當(dāng)前節(jié)點(diǎn)的第一分區(qū),并判斷當(dāng)前分區(qū)中是否空閑大頁,若是,表示可以獲取該空閑大頁,執(zhí)行步驟(a-6),若否,執(zhí)行步驟(a-4);
(a-4)判斷當(dāng)前節(jié)點(diǎn)的下一個(gè)分區(qū)中是否含有空閑大頁,若是,執(zhí)行步驟(a-6),若否,執(zhí)行步驟(a-5);
(a-5)重復(fù)循環(huán)步驟(a-4),直到遍歷當(dāng)前節(jié)點(diǎn)的所有分區(qū)為止,若當(dāng)前節(jié)點(diǎn)的最后一個(gè)分區(qū)不含有空閑大頁,執(zhí)行步驟(a-7)。
(a-6)將空閑大頁的共享計(jì)數(shù)mapcount設(shè)為1,表示當(dāng)前有一個(gè)進(jìn)程在訪問該空閑大頁,并將該大頁從當(dāng)前分區(qū)的活動(dòng)鏈表上去除,同時(shí),由于該頁已被獲取,不再空閑,調(diào)整該分區(qū)中前后大頁的lrui-1、lrui+1,使lrui-1指向后大頁,lrui+1指向前大頁,保持正確指向,返回獲取的大頁,結(jié)束函數(shù);
(a-7)將下一個(gè)節(jié)點(diǎn)作為當(dāng)前節(jié)點(diǎn),執(zhí)行步驟(a-2),直到遍歷所有含有內(nèi)存空間的節(jié)點(diǎn),若遍歷到最后一個(gè)含有內(nèi)存空間的節(jié)點(diǎn)中的最后一個(gè)分區(qū)的所有大頁,未找到空閑大頁,則獲取大頁失敗。
釋放函數(shù)free_page用于將不在使用大頁釋放到大頁內(nèi)存中,具體實(shí)現(xiàn)過程為:
(b-1)判斷當(dāng)前大頁的共享計(jì)數(shù)mapcount是否為1,若是,執(zhí)行步驟(b-2),若否,說明還有其他進(jìn)程在使用,僅將共享計(jì)數(shù)mapcount減1,結(jié)束大頁釋放;
(b-2)判斷是否能夠獲取當(dāng)前大頁所在的節(jié)點(diǎn)及分區(qū)信息,若是,執(zhí)行步驟(b-3),若否,執(zhí)行報(bào)錯(cuò);
(b-3)根據(jù)獲取的當(dāng)前大頁所在的節(jié)點(diǎn)及分區(qū)信息,將該大頁添加至其所在分區(qū)的大頁鏈表上,調(diào)整該大頁的lrui,使lru指向正確的前后大頁,調(diào)整前后大頁的lrui-1、lrui+1,使lrui-1、lrui+1指向該大頁,并將該大頁所屬的分區(qū)的空間大頁數(shù)目加1,將該大頁所屬的節(jié)點(diǎn)的空閑大頁數(shù)目加1,將該大頁的共享計(jì)數(shù)mapcount設(shè)為0,大頁釋放完成。
鎖函數(shù)lock_page實(shí)現(xiàn)將大頁占為己有,禁止其他進(jìn)程訪問,具體實(shí)現(xiàn)過程為:
(c-1)查看當(dāng)前大頁的標(biāo)志flags,判斷當(dāng)前大頁的屬性是否為禁止鎖,若是,退出查看,若否,執(zhí)行步驟(c-2);
(c-2)繼續(xù)查看當(dāng)前大頁的標(biāo)志flags,判斷當(dāng)前大頁是否已經(jīng)被鎖,若是,執(zhí)行步驟(c-3),若否,執(zhí)行步驟(c-4);
(c-3)將當(dāng)前進(jìn)程添加到該大頁所屬節(jié)點(diǎn)的一個(gè)等待隊(duì)列中;
(c-4)將大頁標(biāo)志里flags中的pg_locked設(shè)為1,表示該大頁不能再被其他進(jìn)程訪問,完成該大頁的上鎖。
解鎖函數(shù)unlock_page實(shí)現(xiàn)恢復(fù)大頁自由,可以被其他進(jìn)程訪問,具體過程為:
修改大頁的標(biāo)志flags,將標(biāo)志flags中的pg_locked設(shè)為0,表示該大頁可以被其他進(jìn)程訪問。由于大頁被鎖,之前的所有請(qǐng)求該大頁是進(jìn)程都被添加到該大頁所屬的節(jié)點(diǎn)中的等待隊(duì)列中,此時(shí)大頁被解鎖,將重新喚醒節(jié)點(diǎn)中等待隊(duì)列的進(jìn)程,讓其繼續(xù)運(yùn)行。
以上的大頁內(nèi)存適用于現(xiàn)有的linux系統(tǒng)中,該內(nèi)存構(gòu)架不會(huì)牽涉到小頁系統(tǒng),提升了可擴(kuò)展性。
以上所述的具體實(shí)施方式對(duì)本發(fā)明的技術(shù)方案和有益效果進(jìn)行了詳細(xì)說明,應(yīng)理解的是以上所述僅為本發(fā)明的最優(yōu)選實(shí)施例,并不用于限制本發(fā)明,凡在本發(fā)明的原則范圍內(nèi)所做的任何修改、補(bǔ)充和等同替換等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。