SLIT 表則記錄了各個結(jié)點之間的距離,在系統(tǒng)中由數(shù)組 node_distance[ ] 記錄。
Linux 采用 Node、Zone 和頁三級結(jié)構(gòu)來描述物理內(nèi)存的,如圖 2 所示,
圖 2 Linux 中 Node、Zone 和頁的關(guān)系
. 1 結(jié)點
Linux 用一個 struct pg_data_t 結(jié)構(gòu)來描述系統(tǒng)的內(nèi)存,系統(tǒng)中每個結(jié)點都掛接在一個 pgdat_list 列表中,對 UMA 體系結(jié)構(gòu),則只有一個靜態(tài)的 pg_data_t 結(jié)構(gòu) contig_page_data。對 NUMA 系統(tǒng)來說則非常容易擴充,NUMA 系統(tǒng)中一個結(jié)點可以對應 Linux 存儲描述中的一個結(jié)點,具體描述見 linux/mmzone.h。
|
下面就該結(jié)構(gòu)中的主要域進行說明:
域 | 說明 |
Node_zones | 該結(jié)點的 zone 類型,一般包括 ZONE_HIGHMEM、ZONE_NORMAL 和 ZONE_DMA 三類 |
Node_zonelists | 分配時內(nèi)存時 zone 的排序。它是由 free_area_init_core() 通過 page_alloc.c 中的 build_zonelists() 設置 zone 的順序 |
nr_zones | 該結(jié)點的 zone 個數(shù),可以從 1 到 3,但并不是所有的結(jié)點都需要有 3 個 zone |
node_mem_map | 它是 struct page 數(shù)組的第一頁,該數(shù)組表示結(jié)點中的每個物理頁框。根據(jù)該結(jié)點在系統(tǒng)中的順序,它可在全局 mem_map 數(shù)組中的某個位置 |
Valid_addr_bitmap | 用于描述結(jié)點內(nèi)存空洞的位圖 |
node_start_paddr | 該結(jié)點的起始物理地址 |
node_start_mapnr | 給出在全局 mem_map 中的頁偏移,在free_area_init_core() 計算在 mem_map 和 lmem_map 之間的該結(jié)點的頁框數(shù)目 |
node_size | 該 zone 內(nèi)的頁框總數(shù) |
node_id | 該結(jié)點的 ID,全系統(tǒng)結(jié)點 ID 從 0 開始 |
類型 | 地址范圍 |
ZONE_DMA | 前16MB內(nèi)存 |
ZONE_NORMAL | 16MB – 896MB |
ZONE_HIGHMEM | 896 MB以上 |
Zone是用struct zone_t描述的,它跟蹤頁框使用、空閑區(qū)域和鎖等信息,具體描述如下:
|
下面就該結(jié)構(gòu)中的主要域進行說明:
域 | 說明 |
Lock | 旋轉(zhuǎn)鎖,用于保護該zone |
free_pages | 該zone空閑頁總數(shù) |
pages_min, pages_low, pages_high | Zone的閾值 |
need_balance | 該標志告訴kswapd需要對該zone的頁進行交換 |
Free_area | 空閑區(qū)域的位圖,用于buddy分配器 |
wait_table | 等待釋放該頁進程的隊列散列表,這對wait_on_page()和unlock_page()是非常重要的。當進程都在一條隊列上等待時,將引起進程的抖動 |
zone_mem_map | 全局mem_map中該zone所引用的第一頁 |
zone_start_paddr | 含義與node_start_paddr類似 |
zone_start_mapnr | 含義與node_start_mapnr類似 |
Name | 該zone的名字。如,“DMA”,“Normal”或“HighMem” |
Size | Zone的大小,以頁為單位 |