日期 | 內核版本 | 架構 | 作者 | GitHub | CSDN |
---|---|---|---|---|---|
2017-07-04 | Linux-4.12 | X86 | lwhuq | LinuxMemoryStudy | Linux內存管理 |
1 (N)UMA模型
系統物理內存有兩種管理方式
- UMA(一致內存訪問,uniform memory access)將可用內存以連續方式組織起來(可能有小的缺口)
- NUMA (非一致內存訪問,non-uniform memory access)用於多處理器系統。每個處理器結點管理本地內存,可支持特別快速的訪問。各個處理器結點之前通過總線連接起來,以支持對其他處理器的內存訪問,這個速度就要慢些
2 Linux 基於(N)UMA模型的物理內存組織
Linux通過巧妙辦法把UMA和NUMA的這些差別隱藏了起來,所謂的UMA其實就是隻有一個結點的NUMA。內存的每個結點關聯到系統中的一個處理器內存控制器,每個服務器處理器可以有多個內存控制器,所以每個服務器處理器可以有多個內存結點。在每個結點管理着它的本地內存範圍。內存結點又細分爲內存域,每個內存域管理着一部分內存範圍,有着不同的使用目的。頁面是內存的最小單元,所有的可用物理內存都被細分成頁,頁面的索引就是頁框。
2.1 node結點
數據結構struct pglist_data
用來描述一個node,定義在include/linux/mmzone.h
文件中。並被typedef成pg_data_t。
-
對於NUMA系統來講, 整個系統的內存由一個node_data的pg_data_t指針數組來管理,
-
對於UMA系統(只有一個node),使用struct pglist_data contig_page_data ,作爲系統唯一的node管理所有的內存區域。contig_page_data有兩個定義,一個是bootmem分配器使用在,mm/bootmem.c中,另外一個是memblock分配器使用,在mm/nobootmem.c
宏NODE_DATA(nid)用於定位給定node id的pg_data_t結構,
#define NODE_DATA(nid) (node_data[nid])
2.2 zone內存域
2.2.1 zone_type
基於歷史的原因,x86架構的硬件內存訪問有兩種硬件約束.
-
ISA總線的直接內存存儲DMA處理器只能對內存的前16MB進行尋址
-
在32位計算機中CPU只能尋址4G地址空間。當實際物理內存大於4G時,系統沒有辦法直接映射所有的物理地址。
爲了解決上述硬件約束,Linux定義了三種內存域
- ZONE_DMA用於DMA設備內存分配。
- ZONE_NORMAL用於能直接映射內存分配。
- ZONE_HIGHMEM用於不能直接內存分配,對於64位系統,CPU的地址空間超級大,在可預見的將來所有的物理內存都可以直接映射了,所以ZONE_HIGHMEM在64位系統中就不需要了。
隨着時代的發展,內核又增加了一些新的內存域
- ZONE_DMA32用於32位DMA設備內存分配。
- ZONE_MOVABLE是一個虛擬的內存域,它沒有包含直接的物理內存。後面將看到它是一種防止內存碎片化的技術。
- ZONE_DEVICE用於支持熱插拔設備,例如Non Volatile Memory非易失性內存。
zone_type的定義在include/linux/mmzone.h
enum zone_type {
#ifdef CONFIG_ZONE_DMA
/*
* ZONE_DMA is used when there are devices that are not able
* to do DMA to all of addressable memory (ZONE_NORMAL). Then we
* carve out the portion of memory that is needed for these devices.
* The range is arch specific.
*
* Some examples
*
* Architecture Limit
* ---------------------------
* parisc, ia64, sparc <4G
* s390 <2G
* arm Various
* alpha Unlimited or 0-16MB.
*
* i386, x86_64 and multiple other arches
* <16M.
*/
ZONE_DMA,
#endif
#ifdef CONFIG_ZONE_DMA32
/*
* x86_64 needs two ZONE_DMAs because it supports devices that are
* only able to do DMA to the lower 16M but also 32 bit devices that
* can only do DMA areas below 4G.
*/
ZONE_DMA32,
#endif
/*
* Normal addressable memory is in ZONE_NORMAL. DMA operations can be
* performed on pages in ZONE_NORMAL if the DMA devices support
* transfers to all addressable memory.
*/
ZONE_NORMAL,
#ifdef CONFIG_HIGHMEM
/*
* A memory area that is only addressable by the kernel through
* mapping portions into its own address space. This is for example
* used by i386 to allow the kernel to address the memory beyond
* 900MB. The kernel will set up special mappings (page
* table entries on i386) for each page that the kernel needs to
* access.
*/
ZONE_HIGHMEM,
#endif
ZONE_MOVABLE,
#ifdef CONFIG_ZONE_DEVICE
ZONE_DEVICE,
#endif
__MAX_NR_ZONES
};
- MAX_NR_ZONES是當前系統支持的所有內存域數目
2.3 page frame頁框
3 memory model內存模型
- FLAT memory model - CONFIG_FLATMEM
- Discontiguous Memory Model - CONFIG_DISCONTIGMEM
- Sparse Memory Model - CONFIG_SPARSEMEM和CONFIG_SPARSEMEM_VMEMMAP
3.1 FLAT memory model
3.2 Discontiguous Memory Model
此模式下,CPU訪問物理內存時,物理地址空間是不連續的。所謂的不連續有兩個可能,首先物理地址空間內是有空洞的。其次物理地址空間被分割屬於不同的內存結點。
後者就是NUMA架構。所以在NUMA下都是需要選擇Discontiguous模式。在Discontiguous模式下,在每個內存結點內的物理內存是連續的。
3.3 Sparse Memory Model
上述經典的Sparse模式在執行pfn到page的轉換過程需要插入一個section尋址過程。這樣就導致效率不夠高。而且需要在page->flags內存儲太多信息,各種page flag,node id,zone id,現在由增加section id。不同的處理器架構也無法實現一個一致性的算法。基於此,內核又開發了一個Sparse模式的改進版本Sparse_vmemmap。頁框結構的虛擬首地址通過全局指針vmemmap指定。所有的頁框結構虛擬地址是連續的。當發現一個section時,爲其分配頁框結構,然後建立預訂的虛擬地址到實際頁表的映射。