《深入理解LINUX內(nèi)存管理》學(xué)習(xí)筆記_第1頁(yè)
《深入理解LINUX內(nèi)存管理》學(xué)習(xí)筆記_第2頁(yè)
《深入理解LINUX內(nèi)存管理》學(xué)習(xí)筆記_第3頁(yè)
《深入理解LINUX內(nèi)存管理》學(xué)習(xí)筆記_第4頁(yè)
《深入理解LINUX內(nèi)存管理》學(xué)習(xí)筆記_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、引子為什么要寫(xiě)這個(gè)筆記:1,這本書(shū)的中文版翻譯了太垃圾,沒(méi)法閱讀。閱讀英文原版,可以很好的理解作者的思路。作此筆記備忘2,一直以來(lái)學(xué)習(xí)LINUX kernel的知識(shí)缺乏系統(tǒng)化,借對(duì)這本書(shū)的學(xué)習(xí),系統(tǒng)化的學(xué)習(xí)一下LINUX kernel。3,自己一直在做一個(gè)too small,too simple的單進(jìn)程,特權(quán)模式,64bit保護(hù)模式的稱(chēng)不上OS的,已經(jīng)做完了bootloader, 構(gòu)思kernel的實(shí)現(xiàn)的時(shí)候,困惑在內(nèi)存管理的實(shí)現(xiàn)上,閱讀這本書(shū),希望能有利于自己的OS的編寫(xiě)。4,克服惰性,多讀書(shū),希望一天能閱讀5頁(yè),爭(zhēng)取半年內(nèi)閱讀完這本原版700多頁(yè)的巨著。不足:我不可能完全理解LINUX 內(nèi)

2、存管理的精髓,肯定有很多地方理解錯(cuò)誤。希望大家能夠指正,以便提高,謝謝。學(xué)習(xí)方法:可能您第一次閱讀的時(shí)候很多地方都不理解,不用擔(dān)心。那您可能需要閱讀一些文件系統(tǒng)的知識(shí)?;蛘唛喿x全部筆記后,再回頭閱讀,有些地方您就理解了。言歸正傳:一、概要可用工具CodeViz: 生成代碼調(diào)用關(guān)系圖的工具,這個(gè)工具我現(xiàn)在還沒(méi)有去使用,有興趣的可以自己試試去建立調(diào)用關(guān)系圖。Linux cross reference (LXR): 以web的方式閱讀和查找LINUX內(nèi)核源代碼的工具。這個(gè)工具安裝相當(dāng)麻煩,我建議直接到它的官方網(wǎng)站直接讀代碼。模塊LINUX內(nèi)存管理代碼模塊主要分為4個(gè)部分:1. Out of memo

3、ry 代碼在mm/oom_kill.c 貌似用于殺進(jìn)程的時(shí)候?qū)?nèi)存的操作 2. 虛擬內(nèi)存的分配 代碼在mm/vmalloc.c 3. 物理內(nèi)存頁(yè)面分配 代碼在mm/page_alloc.cVMA(virtual memory addresses)的 創(chuàng)建和進(jìn)程內(nèi)的內(nèi)存區(qū)域的管理 4. 這些模塊,貫穿與其他kernel代碼之中,形成更復(fù)雜的系統(tǒng)模塊,如頁(yè)面替換策略,buffer的輸入輸出等 二、物理內(nèi)存從硬件角度看內(nèi)存系統(tǒng),有2種主流的體系結(jié)構(gòu),不一致的內(nèi)存訪(fǎng)問(wèn)系統(tǒng)(NUMA),我不知道什么系統(tǒng)在用這樣模式,這種系統(tǒng)將內(nèi)存系統(tǒng)分割成2塊區(qū)域 (BANK),一塊是專(zhuān)門(mén)給CPU去訪(fǎng)問(wèn),一塊是給外圍設(shè)

4、備板卡的DMA去訪(fǎng)問(wèn)。另外一種體系結(jié)構(gòu),是一致的內(nèi)存訪(fǎng)問(wèn)系統(tǒng)(UMA),PC都是用的這種結(jié) 構(gòu),這種結(jié)構(gòu)的對(duì)于CPU和其他外圍設(shè)備訪(fǎng)問(wèn)的內(nèi)存在一塊內(nèi)存條上,沒(méi)有任何不同。LINUX內(nèi)核需要支持這2種體系結(jié)構(gòu)。它引入了一個(gè)概念稱(chēng)為node,一個(gè)node對(duì)應(yīng)一個(gè)bank,對(duì)于UMA體系的,系統(tǒng)中只有一個(gè)node。在LINUX中引入一個(gè)數(shù)據(jù)結(jié)構(gòu)“struct pglist_data”,來(lái)描述一個(gè)node,定義在include/linux/mmzone.h文件中。(這個(gè)結(jié)構(gòu)被typedef pg_data_t) 對(duì)于NUMA系統(tǒng)來(lái)講, 整個(gè)系統(tǒng)的內(nèi)存由一個(gè)node_data的pg_data_

5、t指針數(shù)組來(lái)管理。(因?yàn)榭赡苡卸鄠€(gè)node)對(duì)于PC這樣的UMA系統(tǒng),使用struct pglist_data contig_page_data,作為系統(tǒng)唯一的node管理所有的內(nèi)存區(qū)域。(UMA系統(tǒng)中中只有一個(gè)node)每 個(gè)node又被分成多個(gè)zone,它們各自描述在內(nèi)存中的范圍。zone由struct zone_struct 數(shù)據(jù)結(jié)構(gòu)來(lái)描述。zone的類(lèi)型由zone_t表示,有ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM這三種類(lèi)型。它們之間的用途是不一樣的,ZONE_DMA類(lèi)型的內(nèi)存區(qū)域在物理內(nèi)存的低端,主要是ISA設(shè)備只能用低端的地址做 DMA操作。ZONE_

6、NORMAL類(lèi)型的內(nèi)存區(qū)域直接被內(nèi)核映射到線(xiàn)性地址空間上面的區(qū)域(line address space),以后的章節(jié)將詳細(xì)描述。ZONE_HIGHMEM將保留給系統(tǒng)使用。在PC系統(tǒng)中,內(nèi)存區(qū)域類(lèi)型如下分布:ZONE_DMA    0-16MBZONE_NORMAL  16MB-896MBZONE_HIGHMEM 896MB-物理內(nèi)存結(jié)束大多數(shù)kernel的操作只使用ZONE_NORMAL區(qū)域,系 統(tǒng)內(nèi)存由很多固定大小的內(nèi)存塊組成的,這樣的內(nèi)存塊稱(chēng)作為“頁(yè)”(PAGE),x86體系結(jié)構(gòu)中,page的大小為4096個(gè)字節(jié)。每個(gè)物理的頁(yè)由一個(gè) struct p

7、age的數(shù)據(jù)結(jié)構(gòu)對(duì)象來(lái)描述。頁(yè)的數(shù)據(jù)結(jié)構(gòu)對(duì)象都保存在mem_map全局?jǐn)?shù)組中。從載入內(nèi)核的低地址內(nèi)存區(qū)域的后面內(nèi)存區(qū)域,也就是 ZONE_NORMAL開(kāi)始的地方的內(nèi)存的頁(yè)的數(shù)據(jù)結(jié)構(gòu)對(duì)象,都保存在這個(gè)全局?jǐn)?shù)組中。因?yàn)閆ONE_NORMAL區(qū)域的內(nèi)存空間也是有限的,所以L(fǎng)INUX也支持High memory的訪(fǎng)問(wèn),這個(gè)下面章節(jié)會(huì)描述,這個(gè)章節(jié),將主要描述node,zone,page及它們之間的關(guān)聯(lián)。Nodes表示node的數(shù)據(jù)結(jié)構(gòu)為pg_data_t, 也就是struct pglist_data, 這個(gè)結(jié)構(gòu)定義在<linux/mmzone.h>中:typedef struct pgli

8、st_data struct zone node_zonesMAX_NR_ZONES; struct zonelist node_zonelistsMAX_ZONELISTS; int nr_zones; struct page *node_mem_map; struct bootmem_data *bdata; unsigned long node_start_pfn; unsigned long node_present_pages; /* total number of physical pages */ unsigned long node_spanned_pages; /* tota

9、l size of physical page range, including holes */ int node_id; wait_queue_head_t kswapd_wait; struct task_struct *kswapd; int kswapd_max_order; pg_data_t;node_zones: 分別為ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEMnode_zonelists: 分配內(nèi)存操作時(shí)的區(qū)域順序,當(dāng)調(diào)用free_area_init_core()時(shí),由mm/page_alloc.c文件中的build_zonelists()函數(shù)設(shè)置。n

10、r_zones: node中的zone的數(shù)量,1到3個(gè)之間。并不是所有的node都有3個(gè)zone的,比如有些就沒(méi)有ZONE_DMA區(qū)域。node_mem_map: node中的第一個(gè)page,它可以指向mem_map中的任何一個(gè)page。bdata: 這個(gè)僅用于boot 的內(nèi)存分配,下面再描述node_start_pfn: pfn是page frame number的縮寫(xiě)。這個(gè)成員是用于表示node中的開(kāi)始那個(gè)page在物理內(nèi)存中的位置的。 2.4以前的版本,用物理地址來(lái)表示的,后來(lái)由于硬件的發(fā)展,物理內(nèi)存很可能大于32bit所表示 4G的內(nèi)存地址,所以改為以頁(yè)為單位表示。node_prese

11、nt_pages: node中的真正可以使用的page數(shù)量node_spanned_pages: node中所有存在的Page的數(shù)量,包括可用的,也包括被后面講到的mem_map所占用的,dma所占用的區(qū)域的。(做了修正)英文原版是這么描述的:"node spanned pages" is the total area that is addressed by the node, includingany holes that may exist.可能是包括hold的node可以訪(fǎng)問(wèn)的區(qū)域的數(shù)量吧。node_id: node的NODE ID,從0開(kāi)始kswapd_wait:

12、 node的等待隊(duì)列對(duì)于單一node的系統(tǒng),contig_page_data是系統(tǒng)唯一的node數(shù)據(jù)結(jié)構(gòu)對(duì)象。Zone每個(gè)zone都由一個(gè)struct zone數(shù)據(jù)結(jié)構(gòu)對(duì)象描述。zone對(duì)象里面保存著內(nèi)存使用狀態(tài)信息,如page使用統(tǒng)計(jì),未使用的內(nèi)存區(qū)域,互斥訪(fǎng)問(wèn)的鎖(LOCKS)等。 struct zone在<linux/mmzone.h>中定義(把不關(guān)心的NUMA和memory hotplug相關(guān)的成員給省略掉了):struct zone          unsigned long &#

13、160;         free_pages;         unsigned long           pages_min, pages_low, pages_high;         unsigned long   

14、        lowmem_reserveMAX_NR_ZONES;         struct per_cpu_pageset  pagesetNR_CPUS;         spinlock_t             

15、 lock;         struct free_area        free_areaMAX_ORDER;           ZONE_PADDING(_pad1_)  /用于字節(jié)對(duì)齊          spinlock_t  

16、            lru_lock;                struct list_head        active_list;         struct list_head&#

17、160;       inactive_list;         unsigned long           nr_scan_active;         unsigned long       

18、60;   nr_scan_inactive;         unsigned long           nr_active;         unsigned long           nr_inactive

19、;         unsigned long           pages_scanned;         int                  &#

20、160;  all_unreclaimable;          atomic_t                reclaim_in_progress;          atomic_long_t     

21、;      vm_statNR_VM_ZONE_STAT_ITEMS;          int prev_priority;           ZONE_PADDING(_pad2_)  /用于字節(jié)對(duì)齊         wait_queue_head_t 

22、;      * wait_table;         unsigned long           wait_table_hash_nr_entries;         unsigned long       &

23、#160;   wait_table_bits;          struct pglist_data      *zone_pgdat;         unsigned long           zone_start_pfn;  

24、        unsigned long           spanned_pages;         unsigned long           present_pages;     &#

25、160;    const char              *name;  _cacheline_internodealigned_in_smp;free_pages:未分配使用的page的數(shù)量。pages_min, pages_low and pages_high: zone對(duì)page管理調(diào)度的一些參數(shù),下面章節(jié)將講到。lowmem_reserveMAX_NR_ZONES: 為了防止一些代碼必須運(yùn)行在低地址區(qū)域,所以事先

26、保留一些低地址區(qū)域的內(nèi)存。pagesetNR_CPUS: page管理的數(shù)據(jù)結(jié)構(gòu)對(duì)象,內(nèi)部有一個(gè)page的列表(list)來(lái)管理。每個(gè)CPU維護(hù)一個(gè)page list,避免自旋鎖的沖突。這個(gè)數(shù)組的大小和NR_CPUS(CPU的數(shù)量)有關(guān),這個(gè)值是編譯的時(shí)候確定的。lock: 對(duì)zone并發(fā)訪(fǎng)問(wèn)的保護(hù)的自旋鎖free_area: 頁(yè)面使用狀態(tài)的信息,以每個(gè)bit標(biāo)識(shí)對(duì)應(yīng)的page是否可以分配lru_lock: LRU(最近最少使用算法)的自旋鎖reclaim_in_progress: 回收操作的原子鎖active_list: 活躍的page的listinactive_list: 不活躍的page

27、的listrefill_counter:從活躍的page list中移除的page的數(shù)量nr_active: 活躍的page的數(shù)量nr_inactive: 不活躍的page的數(shù)量pressure: 檢查回收page的指標(biāo)all_unreclaimable: 如果檢測(cè)2次還是不能回收zone的page的話(huà),則設(shè)置為1pages_scanned: 上次回收page后,掃描過(guò)的page的數(shù)量。wait_table:等待一個(gè)page釋放的等待隊(duì)列哈希表。它會(huì)被wait_on_page(),unlock_page()函數(shù)使用. 用哈希表,而不用一個(gè)等待隊(duì)列的原因,防止進(jìn)程長(zhǎng)期等待資源。wait_tabl

28、e_hash_nr_entries: 哈希表中的等待隊(duì)列的數(shù)量zone_pgdat: 指向這個(gè)zone所在的pglist_data對(duì)象。zone_start_pfn: 和node_start_pfn的含義一樣。這個(gè)成員是用于表示zone中的開(kāi)始那個(gè)page在物理內(nèi)存中的位置的present_pages, spanned_pages: 和node中的類(lèi)似的成員含義一樣。zone: zone的名字,字符串表示: "DMA","Normal" 和"HighMem"ZONE_PADDING: 由于自旋鎖頻繁的被使用,因此為了性能上的考慮,將某

29、些成員對(duì)齊到cache line中,有助于提高執(zhí)行的性能。使用這個(gè)宏,可以確定 zone->lock,zone->lru_lock,zone->pageset這些成員使用不同的cache line.Zone的管理調(diào)度的一些參數(shù): (Zone watermarks),英文直譯為zone的水平,打個(gè)比喻,就像一個(gè)水庫(kù),水存量很小的時(shí)候加大進(jìn)水量,水存量達(dá)到一個(gè)標(biāo)準(zhǔn)的時(shí)候,減小進(jìn)水量,當(dāng)快要滿(mǎn)的時(shí)候,可能就關(guān)閉了進(jìn)水口。pages_min, pages_low and pages_high就類(lèi)似與這個(gè)標(biāo)準(zhǔn)。當(dāng)系統(tǒng)中可用內(nèi)存很少的時(shí)候,系統(tǒng)代碼kswapd被喚醒,開(kāi)始回收釋放page

30、。pages_min, pages_low and pages_high這些參數(shù)影響著這個(gè)代碼的行為。每個(gè)zone有三個(gè)水平標(biāo)準(zhǔn):pages_min, pages_low and pages_high,幫助確定zone中內(nèi)存分配使用的壓力狀態(tài)。kswapd和這3個(gè)參數(shù)的互動(dòng)關(guān)系如下圖:page_min中所表示的page的數(shù)量值,是在內(nèi)存初始化的過(guò)程中調(diào)用free_area_init_core()中計(jì)算的。這個(gè)數(shù)值是根據(jù)zone中的page的數(shù)量除以一個(gè)>1的系數(shù)來(lái)確定的。通常是這樣初始化的ZoneSizeInPages/128。page_low: 當(dāng)空閑頁(yè)面的數(shù)量達(dá)到page_low所標(biāo)

31、定的數(shù)量的時(shí)候,kswapd線(xiàn)程將被喚醒,并開(kāi)始釋放回收頁(yè)面。這個(gè)值默認(rèn)是page_min的2倍。 page_min: 當(dāng)空閑頁(yè)面的數(shù)量達(dá)到page_min所標(biāo)定的數(shù)量的時(shí)候, 分配頁(yè)面的動(dòng)作和kswapd線(xiàn)程同步運(yùn)行page_high: 當(dāng)空閑頁(yè)面的數(shù)量達(dá)到page_high所標(biāo)定的數(shù)量的時(shí)候, kswapd線(xiàn)程將重新休眠,通常這個(gè)數(shù)值是page_min的3倍。zone的大小的計(jì)算setup_memory()函數(shù)計(jì)算每個(gè)zone的大?。?#160;PFN 是物理內(nèi)存以Page為單位的偏移量。系統(tǒng)可用的第一個(gè)PFN是min_low_pfn變量,開(kāi)始與_end標(biāo)號(hào)的后面,也就是kern

32、el結(jié)束的地方。 在文件mm/bootmem.c中對(duì)這個(gè)變量作初始化。系統(tǒng)可用的最后一個(gè)PFN是max_pfn變量,這個(gè)變量的初始化完全依賴(lài)與硬件的體系結(jié)構(gòu)。 x86的系統(tǒng)中,find_max_pfn()函數(shù)通過(guò)讀取e820表獲得最高的page frame的數(shù)值。同樣在文件mm/bootmem.c中對(duì)這個(gè)變量作初始化。e820表是由BIOS創(chuàng)建的。x86 中,max_low_pfn變量是由find_max_low_pfn()函數(shù)計(jì)算并且初始化的,它被初始化成ZONE_NORMAL的最后一個(gè)page 的位置。這個(gè)位置是kernel直接訪(fǎng)問(wèn)的物理內(nèi)存,也是關(guān)系到kernel/userspace通過(guò)

33、“PAGE_OFFSET宏”把線(xiàn)性地址內(nèi)存空間分 開(kāi)的內(nèi)存地址位置。(原文:This is the physical memory directly accessibleby the kernel and is related to the kernel/userspace split in the linear address spacemarked by PAGE OFFSET.)我理解為這段地址kernel可以直接訪(fǎng)問(wèn),可以通過(guò)PAGE_OFFSET宏直接將kernel所用的虛擬地址轉(zhuǎn)換成物理地址的區(qū)段。 在文件mm/bootmem.c中對(duì)這個(gè)變量作初始化。在內(nèi)存比較小的系統(tǒng)中max_p

34、fn和max_low_pfn的值相同。min_low_pfn, max_pfn和max_low_pfn這3個(gè)值,也要用于對(duì)高端內(nèi)存(high memory)的起止位置的計(jì)算。在arch/i386/mm/init.c文件中會(huì)對(duì)類(lèi)似的highstart_pfn和highend_pfn變量作 初始化。這些變量用于對(duì)高端內(nèi)存頁(yè)面的分配。后面將描述。Zone等待隊(duì)列表(zone wait queue table)當(dāng) 對(duì)一個(gè)page做I/O操作的時(shí)候,I/O操作需要被鎖住,防止不正確的數(shù)據(jù)被訪(fǎng)問(wèn)。進(jìn)程在訪(fǎng)問(wèn)page前,調(diào)用wait_on_page()函數(shù),使進(jìn) 程加入一個(gè)等待隊(duì)列。訪(fǎng)問(wèn)完成后,Unlock

35、Page()函數(shù)解鎖其他進(jìn)程對(duì)page的訪(fǎng)問(wèn)。其他正在等待隊(duì)列中的進(jìn)程被喚醒。每個(gè)page都可以有一 個(gè)等待隊(duì)列,但是太多的分離的等待隊(duì)列使得花費(fèi)太多的內(nèi)存訪(fǎng)問(wèn)周期。替代的解決方法,就是將所有的隊(duì)列放在struct zone數(shù)據(jù)結(jié)構(gòu)中。也 可以有一種可能,就是struct zone中只有一個(gè)隊(duì)列,但是這就意味著,當(dāng)一個(gè)page unlock的時(shí)候,訪(fǎng)問(wèn)這個(gè)zone里內(nèi)存page的所有休眠的進(jìn)程將都被喚醒,這樣就會(huì)出現(xiàn)擁堵(thundering herd)的問(wèn)題。建立一個(gè)哈希表管理多個(gè)等待隊(duì)列,能解決這個(gè)問(wèn)題,zone->wait_table就是這個(gè)哈希表。哈希表的方法可能還是會(huì)造 成一些

36、進(jìn)程不必要的喚醒。但是這種事情發(fā)生的機(jī)率不是很頻繁的。下面這個(gè)圖就是進(jìn)程及等待隊(duì)列的運(yùn)行關(guān)系:等待隊(duì)列的哈希表的分配和建立在free_area_init_core()函數(shù)中進(jìn)行。哈希表的表項(xiàng)的數(shù)量在wait_table_size()函 數(shù)中計(jì)算,并且保持在zone->wait_table_size成員中。最大4096個(gè)等待隊(duì)列。最小是NoPages / PAGES_PER_WAITQUEUE的2次方,NoPages是zone管理的page的數(shù)量,PAGES_PER_WAITQUEUE被定義 256。(原文:For smaller tables, the size of the table

37、is the minimum power of 2 required to store NoPages / PAGES PER WAITQUEUEnumber of queues, where NoPages is the number of pages in the zone andPAGE PER WAITQUEUE is defined to be 256.)下面這個(gè)公式可以用于計(jì)算這個(gè)值: zone->wait_table_bits 用于計(jì)算:根據(jù)page 地址得到需要使用的等待隊(duì)列在哈希表中的索引的算法因子。page_waitqueue()函數(shù)負(fù)責(zé)返回zone中pag

38、e所對(duì)應(yīng)等待隊(duì)列。它用一個(gè)基于 struct page虛擬地址的簡(jiǎn)單的乘法哈希算法來(lái)確定等待隊(duì)列的。page_waitqueue()函數(shù)用GOLDEN_RATIO_PRIME的地址和“右移zonewait_table_bits一個(gè)索引值”的一個(gè)乘積來(lái)確定等待隊(duì)列在哈希表中的索引的。Zone的初始化在kernel page table通過(guò)paging_init()函數(shù)完全建立起z來(lái)以后,zone被初始化。下面章節(jié)將描述這個(gè)。當(dāng)然不同的體系結(jié)構(gòu)這個(gè)過(guò)程肯定也是不一樣 的,但它們的目的卻是相同的:確定什么參數(shù)需要傳遞給free_area_init()函數(shù)(對(duì)于UMA體系結(jié)構(gòu))或者 free_area

39、_init_node()函數(shù)(對(duì)于NUMA體系結(jié)構(gòu))。這里省略掉NUMA體系結(jié)構(gòu)的說(shuō)明。free_area_init()函數(shù)的參數(shù):unsigned long *zones_sizes:  系統(tǒng)中每個(gè)zone所管理的page的數(shù)量的數(shù)組。這個(gè)時(shí)候,還沒(méi)能確定zone中那些page是可以分配使用的(free)。這個(gè)信息知道boot memory allocator完成之前還無(wú)法知道。初始化mem_mapmem_map是一個(gè)struct page的數(shù)組,管理著系統(tǒng)中所有的物理內(nèi)存頁(yè)面。在系統(tǒng)啟動(dòng)的過(guò)程中,創(chuàng)建和分配mem_map的內(nèi)存區(qū)域。UMA體系結(jié)構(gòu) 中,free_area_init

40、()函數(shù)在系統(tǒng)唯一的struct node對(duì)象contig_page_data中node_mem_map成員賦值給全局的mem_map變量。調(diào)用的關(guān)系圖:主要的核心函數(shù)free_area_init_core(),為node的初始化過(guò)程分配本地的 lmem_map(node->node_mem_map)。數(shù)組的內(nèi)存在boot memory 分配的alloc_bootmem_node()函數(shù)分配.在UMA體系結(jié)構(gòu)中,這個(gè)新分配的lmem_map成為全局的mem_map. 對(duì)于NUMA體系,lmem_map賦值給每一個(gè)node的node_mem_map成員,而這個(gè)情況下mem_map就被簡(jiǎn)單的

41、賦值為 PAGE_OFFSET(有興趣理解NUMA體系結(jié)構(gòu)的可以閱讀英文原版,了解更多信息)。UMA體系中,node中的各個(gè)zone的 zone_mem_map就指向mem_map中的某些元素作為zone所管理的第一個(gè)page的地址。Page系統(tǒng)中的每個(gè)物理頁(yè)面用struct page數(shù)據(jù)結(jié)構(gòu)對(duì)象來(lái)表示,并且跟蹤page使用的狀態(tài):(省略了一些特定平臺(tái)用到的成員)struct page         unsigned long flags;       

42、           atomic_t _count;        union                 atomic_t _mapcount;            &#

43、160;    unsigned int inuse;         ;        union             struct                

44、 unsigned long private;                struct address_space *mapping;            ;            struct kmem_cache *sl

45、ab;    /* SLUB: Pointer to slab */            struct page *first_page;    /* Compound tail pages */        ;        union     

46、;            pgoff_t index;          /* Our offset within mapping. */                void *freelist;    &

47、#160;    /* SLUB: freelist req. slab lock */        ;        struct list_head lru;       #if defined(WANT_PAGE_VIRTUAL)         void *virtua

48、l;#endif         ;union                 atomic_t _mapcount;                 unsigned int inuse;   &#

49、160;     : 和頁(yè)表轉(zhuǎn)換有關(guān)的PTE鏈,下面章節(jié)將描述。index:這個(gè)成員根據(jù)page的使用的目的有2種可能的含義。第一種情況:如果page是file mapping的一部分,它指明在文件中的偏移。如果page是交換緩存,則它指明在address_space所聲明的對(duì) 象:swapper_space(交換地址空間)中的偏移。第二種情況:如果這個(gè)page是一個(gè)特殊的進(jìn)程將要釋放的一個(gè)page塊,則這是一個(gè)將要釋放 的page塊的序列值,這個(gè)值在_free_page_ok()函數(shù)中設(shè)置。mapping: 當(dāng)文件或設(shè)備需要內(nèi)存映射,文件或設(shè)備的ino

50、de對(duì)象有一個(gè)address_space類(lèi)型的成員。如果page屬于這個(gè)文件或設(shè)備,mapping將 指向inode中這個(gè)成員。如果page不屬于任何文件或設(shè)備,但是 mapping被設(shè)置了,則mapping指向了一個(gè)address_space類(lèi)型的swapper_space對(duì)象,則page用于管理交換地址空間 (swap address space)了。lru: page交換調(diào)度策略使用。page可能被調(diào)度到active_list或者inactive_list隊(duì)列里。就是使用lru這個(gè)list_head。private:這個(gè)保存了一些和mapping(文件mapping到內(nèi)存)有關(guān)的一些特定

51、的信息。如果page是一個(gè)buffer page,則它就保存了一個(gè)指向buffer_head的指針。virtual: 不再用于將high memory的映射到ZONE_NORMAL區(qū)域的作用了,除了一些其他的體系結(jié)構(gòu)會(huì)用到外。count: page的訪(fǎng)問(wèn)計(jì)數(shù),當(dāng)為0是,說(shuō)明page是空閑的,當(dāng)大于0的時(shí)候,說(shuō)明page被一個(gè)或多個(gè)進(jìn)程真正使用或者kernel用于在等待I/O。flags:  page狀態(tài)的標(biāo)志信息。kernel代碼里定義了大量的宏用于設(shè)置,清楚,檢測(cè)flag成員中的各個(gè)位所表示的page狀態(tài)信息。特別提示一 下,SetPageUptodate(),它需要調(diào)用一個(gè)和體系結(jié)構(gòu)有關(guān)的函數(shù):arch_set_page_uptodate().映射頁(yè)面到zone(Mapping page to zones)在struct zone *zone_table1 << ZONETABLE_SHIFT _read_mostly;EXPORT_SYMBOL(zone_table);EXPORT_SYMBOL宏的作用,是讓zone_table能夠被其他載入的模塊使用。free

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論