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