dpdk記憶體管理 初始化

2021-09-01 20:01:51 字數 2574 閱讀 4340

dpdk的記憶體初始化工作,主要是將hugetlbfs的配置的大記憶體頁,根據其對映的實體地址是否連續、屬於哪個socket等,有效的組織起來,為後續管理提供便利。

eal_hugepage_info_init()

主要是獲取配置好的hugetlbfs的相關資訊,並將其儲存在struct internal_config資料結構中。

讀取/sys/kernel/mm/hugepages目錄下的各個子目錄,通過判斷目錄名稱中包含"hugepages-"字串,獲取hugetlbfs的相關子目錄,並獲取hugetlbfs配置的記憶體頁大小。

通過讀取/proc/mounts資訊,找到hugetlbfs的掛載點

以開啟檔案的方式,開啟掛載點目錄,為其fd設定互斥鎖

hpi->hugepage_sz = 2m;

hpi->hugedir = /mnt/huge;

hpi->num_pages[0] = 64; // 由於此時還不知道哪些記憶體頁分處在哪個socket上,故,都先放在socket-0上。

hpi->lock_descriptor = open(hpi->hugedir, o_ronly); // 在讀取hugetlbfs配置的時候,需要鎖住整個目錄。當所有hugepage都mmap完成後,會解鎖。

rte_eal_config_create()

rte_eal_config_create()主要是初始化rte_config.mem_config。如果是以root使用者執行dpdk程式的話,rte_config.mem_config指向/var/run/.rte_config檔案mmap的一段sizeof(struct rte_mem_config)大小的記憶體。用於管理整個記憶體。

rte_eal_hugepage_init()

rte_eal_hugepage_init()主要是在/mnt/huge目錄下建立hugetlbfs配置的記憶體頁數的rtemap_xx檔案,並為每個rtemap_xx檔案做mmap對映,保證mmap後的虛擬位址與實際的實體地址 一致性。

有多少個記憶體頁,在掛載點目錄下建立多少個rtemap_xx檔案,如下所示,並為每乙個檔案mmap乙個hugepage_sz大小的記憶體區域。

通過讀取/proc/self/pagemap頁表檔案,得到本程序中虛擬位址與實體地址的對映關係。使用上一步中,每個rtemap_xx檔案mmap得到的虛擬位址,除以作業系統記憶體頁的大小4k,得到乙個偏移量。根據這個偏移量,在/prox/self/pagemap中,得到實體地址的頁框,假設為page,那麼,物理頁框page乘以作業系統記憶體頁的大小4k,再加上虛擬位址的頁偏移,就是實體地址。每個rtemap_xx對映的實體地址儲存在對應的hugepage_file->physaddr中。

讀取/proc/self/numa_maps,得到每個rtemap_xx檔案mmap得到的虛擬位址在哪個socket上,即,哪個cpu上。其socketid儲存在對應的hugepage_file->socket_id中

在hugepage_file陣列中,根據實體地址,按從小到大的順序,將hugepage_file排序。

根據按實體地址排序後的結果,判斷實體地址是否連續,重新mmap /mnt/huge/retmap_xx檔案,第二次mmap得到的虛擬位址儲存在對應的hugepage_file->final_va中。

munmap釋放第一步中各個rtemap_xx檔案首次mmap得到的記憶體位址。

計算每個socket上包含多少個hugepage,資訊儲存在internal_config.hugepage_info[0].num_pages[socket]中。

rte_config.mem_config->memseg陣列記錄hugepage_file對映後實體地址連續的塊數,hugepage_file->memseg_id為該huepage_file的實體地址在哪個rte_config.mem_config->memseg陣列中。

rte_config.mem_config->memseg[j].phys_addr = 各實體地址是連續的記憶體塊的首位址。

rte_config.mem_config->memseg[j].addr = 各個實體地址是連續的記憶體塊對應的虛擬位址的首位址。由於實體地址和虛擬位址是相同的,這個值應該等於phys_addr。

rte_config.mem_config->memseg[j].len = 各個實體地址是連續的記憶體塊的大小。

rte_config.mem_config->memseg[j].socket_id = 記憶體塊在哪個socket上。。

rte_config.mem_config->memseg[j].hugepage_sz = hugepage記憶體頁的大小。本文中是2m。

rte_eal_memzone_init()

rte_eal_memzone_init()主要負責初始化rte_config.mem_config->free_memseg及rte_config.mem_config->memzone。其中,rte_config.mem_config->free_memseg記錄空閒的rte_config.mem_config->memseg。

DPDK的RTE INIT初始化

dpdk 中廣泛使用rte init巨集進行裝置驅動或者rte模組等的初始化工作,其核心是rte init prio巨集,定義在檔案rte common.h中。如下可見,rte init prio巨集的實現,實際為乙個附帶gcc編譯屬性的函式定義。此處用到兩個屬性,constructor和used。...

記憶體初始化

電容的分類 dram 基本原件是電容,需要定時重新整理,儲存速度較慢 dram又分為 sram 同步動態隨機儲存器 synchronous dynamic random access memory ddr 雙倍速率同步動態隨機儲存器 double data rate sdram ddr2 在 ddr...

記憶體初始化過程

1,物理記憶體資訊的獲取 0x15中斷,功能號 e820h,e801h,e88h 見檔案 linux arch i386 boot setup.s 執行完上面的 後,記憶體資訊被分為多條資訊放在e820map位置處,每個資訊條目長20位元組,包含乙個記憶體區間的資訊,條目數放在e820nr處。即實際...