typedef struct pglist_data {zone_t node_zones[MAX_NR_ZONES];zonelist_t node_zonelists[GFP_ZONEMASK+1];int nr_zones;struct page *node_mem_map;unsigned long *valid_addr_bitmap;struct bootmem_data *bdata;unsigned long node_start_paddr;unsigned long node_start_mapnr;unsigned long node_size;int node_id;struct pglist_data *node_next;} pg_data_t;下面就該結構中的主要域進行說明: 域說明 Node_zones該結點的zone類型,一般包括ZONE_HIGHMEM、ZONE_NORMAL和ZONE_DMA三類 Node_zonelists 分配時內存時zone的排序。它是由free_area_init_core()通過page_alloc.c中 build_zonelists() 設置 zone 的順序nr_zones 該結點的zone個數,可以從1到3,但並不是所有的結點都需要有3個 zonenode_mem_map它是struct page數組的第一頁,該數組表示結點中的每個物理頁框。根據該結點在系統中的順序,它可在全局 mem_map數組中的某個位Valid_addr_bitmap用於描述結點內存空洞的位圖,node_start_paddr該結點的起始物理地址。 node_start_mapnr給出在全局mem_map中的頁偏移,在free_area_init_core()計算在mem_map和 lmem_map之間的該結點的頁框數目,node_size該zone內的頁框總數,node_id該結點的ID,全系統結點ID從0開始。系統中所有結點都維護在pgdat_list列表中,在init_bootmem_core函數中完成該列表初始化工作。 2.2 Zone 每個結點的內存被分為多個塊,稱為zones,它表示內存中一段區域。一個zone用struct_zone_t結構描述,zone的類型主要有 ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_DMA位於低端的內存空間,用於某些舊的ISA設備。 ZONE_NORMAL的內存直接映射到Linux內核線性地址空間的高端部分,許多內核操作只能在ZONE_NORMAL中進行。例如,在X86中, zone的物理地址如下: 類型 地址范圍 ZONE_DMA前16MB內存;ZONE_NORMAL 16MB - 896MB;ZONE_HIGHMEM 896 MB以上。Zone是用struct zone_t描述的,它跟蹤頁框使用、空閒區域和鎖等信息,具體描述如下:
typedef struct zone_struct {spinlock_t lock;unsigned long free_pages;unsigned long pages_min, pages_low, pages_high;int need_balance;free_area_t free_area[MAX_ORDER];wait_queue_head_t * wait_table;unsigned long wait_table_size;unsigned long wait_table_shift;struct pglist_data *zone_pgdat;struct page *zone_mem_map;unsigned long zone_start_paddr;unsigned long zone_start_mapnr;char *name;unsigned long size;} zone_t;下面就該結構中的主要域進行說明: 域說明 Lock旋轉鎖,用於保護該zone,free_pages 該zone空閒頁總數pages_min,pages_low, pages_high Zone的阈值,need_balance 該標志告訴kswapd需要對該zone的頁進行交換,Free_area 空閒區域的位圖,用於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的大小,以頁為單位。 當系統中可用的內存比較少時,kswapd將被喚醒,並進行頁交換。如果需要內存的壓力非常大,進程將同步釋放內存。如前面所述,每個zone有三個阈值,稱為pages_low,pages_min和pages_high,用於跟蹤該zone的內存壓力。pages_min的頁框數是由內存初始化 free_area_init_core函數,根據該zone內頁框的比例計算的,最小值為20頁,最大值一般為255頁。當到達pages_min時,分配器將采用同步方式進行kswapd的工作;當空閒頁的數目達到pages_low時,kswapd被buddy分配器喚醒,開始釋放頁;當達到 pages_high時,kswapd將被喚醒,此時kswapd不會考慮如何平衡該zone,直到有pages_high空閒頁為止。一般情況下, pages_high缺省值是pages_min的3倍。 Linux存儲管理的這種層次式結構可以將ACPI的SRAT和SLIT信息與Node、Zone實現有效的映射,從而克服了傳統Linux中平坦式結構無法反映NUMA架構的缺點。當一個任務請求分配內存時,Linux采用局部結點分配策略,首先在自己的結點內尋找空閒頁;如果沒有,則到相鄰的結點中尋找空閒頁;如果還沒有,則到遠程結點中尋找空閒頁,從而在操作系統級優化了訪存性能。 更多內容請看Linux服務器配置 操作系統 系統管理專題,或