您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關怎么進行Linux系統內核架構分析,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
1:在內核使用高端內存頁之前,必須使用下文討論的kmap和kunmap函數將其映射到內存虛擬地址空間中。
2:UMA計算機(一致內存訪問,uniform memory access)將可用內存以連續方式組織起來。
3:NUMA計算機(非一致性內存訪問,non-uniform memory access)系統的各個CPU都有本地內存,可支持特別快速的訪問,各個處理器之間通過總線連接起來,以支持其他CPU的本地內存的訪問。
4:內核會區分三種配置選項:FLATTMEM,DISCONTIGMEM,SPARSEMEM,DISCONTIGMEM.
5:內存劃分為結 點。每個節點關聯到系統中的一個處理器。在內核中表示為pg_data_t的實例。
6:各個結點又劃分為 內存域,是內存域的進一步細分。
7:
注:zonelist:指向zonelist數據結構的指針,該數據結構按照優先次序描述了適于內存分配的內存管理區。
8:
1)ZONE_DMA標記適合DMA的內存域。
2)ZONE_DMA32標記了使用32位地址字可尋址,適合DMA的內存域。
3)ZONE_NORMAL標記了可直接映射到內核段的普通內存域,這是在所有體系結構上保證都會存在的唯一內存域,但無法保證該地址范圍對應了實際的物理內存。
4)ZONE_HIGHMEM標記了超出內核段的物理內存。
5)偽內存域ZONE_MOVABLE.
6)MAX_NR_ZONES充當結束標志,在內核想要迭代系統中的所有內存域時,會用到該常量。
7)各個內存域都關聯了一個數組,用來組織屬于該內存域的物理內存頁(頁幀)。對每個頁幀,都分配一個struct page實例以及所需的管理數據。
8)每個節點都提供了一個備用列表(借助struct zonelist)。該列表包含了其他節點(和相關的內存域),可用于代替當前節點分配內存。
3.2.2數據結構
1)結點管理
pg_data_t用于表示節點的基本元素。
typedef struct pglist_data{ struct zone node_zones[MAX_NR_ZONES]; struct zonelist node_zonelists[MAX_ZONELISTS]; int nr_zones; struct page*node_mem_map; struct bootmem_data *bdata; unsigned long node_start_pfn; unsigned long node_present_pages;/*物理內存頁的總數*/ unsighed long node_spanned_pages;/*物理內存頁的總數,包含洞在內*/ int node_id; struct pglist_data *pgdat_next; wait_queue_head_t kswapd_wait; struct task_struct *ksward; int ksward_max_order;}pg_data_t;
注:1)node_zones是一個數組,包含了節點中各內存域的數據結構。
2)node_zonelists指定了備用節點及其內存域的列表,以便在當前節點沒有可用空間時,在備用節點分配內存。
3)節點中不同內存域的數目保存在nr_zones中
4)node_mem_map是指向page實例數組的指針,用于描述節點的所有物理內存頁,它包含了節點中所有內存域的頁。
5)bdata指向自舉內存分配器數據結構的實例。
6)node_start_pfn是該NUMA節點第一個頁幀的邏輯編號。所有頁幀是依次編號的,每個頁幀的號碼都是全局唯一的。
在UMA中總是0.
7)node_present_pages指定了節點中頁幀的數目,node_spanned_pages則給出了該節點以頁幀 為單位計算的長度。
8)node_id是全局節點ID。
9)pgdat_next連接到下一個內存節點,系統中所有的內存節點都通過單鏈表連接起來,其末尾通過空指針標記。
10)kswapd_wait是交換守護進程(swap daemon)的等待隊列,將在頁幀換出節點時會用到。
kswapd指向負責該節點的交換守護進程的task_struct.
kswapd_max_order用于頁交換子系統的實現,用來定義需要釋放的區域的長度。
11)節點的內存域保存在node_zones[MAX_NR_ZONES].該數組總是有3項。即使節點沒有那么多內存域,若不足3個,則其余的數組項用0填充。
enum node_states{ N_POSSIBLES, /*節點在某個時候可能變成聯機*/ N_ONLINE, /*節點是聯機的*/ N_NORMAL_MEMORY, /*幾點有普通內存域*/#ifdef CONFIG_HIGHMEM N_HIGH_MEMORY, /*節點有普通或高端內存域*/#else N_HIGH_MEMORY = N_NORMAL_MEMORY,#endif N_CPU, /*節點有一個或者多個CPU*/ NR_NODE_STATES};
注:如果節點有普通或高端內存則使用N_HIGH_MEMORY,僅當節點沒有高端內存才設置N_NORMAL_MEMORY.
2)內存域
內核使用zone結構來描述內存域。
struct zone{
/*通常由頁分配器訪問的字段*/
unsigned long pages_min,pages_low,pages_high; 注:1)若空閑頁的數目多于pages_high,則內存域的狀態是理想的
2)若空閑頁的數目低于pages_low,則內核開始將頁換出到硬盤
3)若空閑頁的數目低于pages_min,內存域急需空閑頁,需頁回收
4)數據結構中水印值得填充由init_per_zone_pages_min處理。
5)setup_per_zone_pages_min設置struct zone的pages_min,
pages_low,pages_high成員。
unsigned long lowmem_reserve[MAX_NR_ZONES]; 注:該數組分別為各種內存域指定了若干項,用于一些無論如何都不能失敗 的關鍵性內存分配。
struct per_cpu_pageset pageset[NR_CPUS]; 注:該數組用于實現每個CPU的熱/冷頁幀列表。內核使用這些列表保存可 用于滿足實現的“新鮮”頁。
熱頁幀:在高速緩存中,可以快速訪問,
冷頁幀:不在高速緩存中的頁幀
NR_CPUS是一個可以在編譯時間配置的宏常數。
注:數組元素的類型為per_cpu_pageset
struct per_cpu_pageset{ struct per_cpu_pages pcp[2];/*索引0對應熱頁,索引1對應冷頁*/}__cacheline_aligned_in_smp;
注:該結構由一個帶有數組項的數組構成,第一項管理熱頁。第二頁管理冷頁。
有用的數據保存在per_cpu_pages中。
struct per_cpu_pages{ int count; /*與該列表相關的頁的數目*/ int high; /*high是頁數上限水印,在需要的時候清空列表。若count的值超出high,即列表中的 頁數太多*/ int batch; /*添加/刪除多項頁的時候,塊的大小*/ struct list_head list; /*list是頁的雙鏈表,保存當前CPU的冷頁或者熱頁*/}
“
/*
*不同長度的空閑區域
*/
spinlock_t lock;
struct free_area free_area[MAX_OEDER]; 注:是同名數據結構的數組,用于實現伙伴系統,每個數組元素都表示某種 固定長度的一些連續的內存區。對于包含在每個區域中的空閑內存頁 的管理。free_area是一個起點。
ZONE_PAGGING(_pad1_)
/*通常由頁面收回掃描程序訪問的字段*/
spinlock_t lru_lock;
struct list_head active_list; 注:是活動頁的集合
struct list_head inactive_list; 注:是不活動頁的集合
unsighed long nr_scan_active; 注:回收內存時需要掃描的活動頁的數目
unsighed long nr_scan_inactive; 注:回收內存時需要掃描的不活動頁的數目
unsighed long pages_scanned; 注:上次回收以來掃描過的頁
unsighed long flags; 注:描述內存域當前狀態
typedef enum { ZONE_ALL_UNERCLAIMABLE, /*所有的頁都已經釘住,不能回收*/ ZONE_RECLAIM_LOCKED, /*防止并發回收*/ ZONE_OOM_LOCKED, /*內存域即可被回收*/}zone_flags_t;
/*內存域統計量*/
atmoic_long_t vm_stat[NR_VM_STAT_ITEMS]; 注:維護了大量有關內存域的統計信息。輔助函數zone_page_state用來 讀取vm_stat中的信息
int prev_priority; 注:存儲了上一次掃描操作掃描該內存域的優先級。掃描操作是由try_to _free_pages進行的,直至釋放了足夠多的頁幀。
ZONE_PAGGING(_pad2_)
/*很少使用或大多數情況下只讀的字段*/
wait_queue_head_t *wait_table; 注:是一個等待隊列,可用于等待某一頁變為可用進程。進程排成一個隊 ``
unsighed long wait_table_hash_nr_entries;列,等待某些條件, 在條件為真時,內核會通知進程恢復工作。
unsighed long wait_table_bits;
/*支持不連續內存模型的字段*/
struct pglist_data *zone_pgdat; 注:內存域和父節點之間的關聯由zone_pgdat建立,zone_pgdat指向對 應的pg_list_data實例
unsighed long zone_start_pfn; 注:內存域第一個頁幀的索引
unsighed long spanned_pages; /*總長度,包括空洞*/
unsighed long present_pages; /*總長度,不包括空洞*/實際上可用的頁數目
/*
*很少使用的字段
*/
char *name; 注:是一個字符串,保存該內存域的慣用名稱。3個選項可用,Normal,
DMA,HighMem
}__cacheline_maxaligned_in_smp;
3.內存域水印的計算
在計算水印之前,內核首先確定需要為關鍵性分配保留的內存空間的最小值。該值隨可用內存的大小而非線性增長,并保留在全局變量min_free_kbytes中。
注:1)高端內存域的下界SWAP_CLUSTER_MAX.
2)它定義了分組的大小。
3)setup_per_zone_lowmem_reserve計算出lowmem_reserve
上述就是小編為大家分享的怎么進行Linux系統內核架構分析了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。