Overview - Linux內存管理(1)


日期 內核版本 架構 作者 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頁框

  頁框是系統內存的最小單位。對內存中的每個頁都會創建struct page實例。內核需要注意保持該結構儘可能小。因爲即便在中等程度內存配置下,系統的內存同樣會分解爲大量的頁。例如當頁長度爲4KB,主內存384MB時大約需要100000頁。
  系統中定義了page_to_pfn和pfn_to_page的宏用來在page frame number和page數據結構之間進行轉換,具體如何轉換是和memory model相關。

3 memory model內存模型 

linux內存模型有三種
  • FLAT memory model - CONFIG_FLATMEM
  • Discontiguous Memory Model - CONFIG_DISCONTIGMEM
  • Sparse Memory Model - CONFIG_SPARSEMEM和CONFIG_SPARSEMEM_VMEMMAP

3.1 FLAT memory model

  此模式下,CPU訪問物理內存時,物理地址空間是一個連續的,沒有空洞的地址空間。每一個物理的頁幀有一個page結構來抽象描述,每個page結構都是系統全局page結構指針(mem_map)的一個偏移。也就是說頁框號PFN和mem_map的偏移index直接是線性關聯的(存在一個固定偏移或直接相等)。因此在此模式下系統只有一個內存結點。

3.2 Discontiguous Memory Model

  此模式下,CPU訪問物理內存時,物理地址空間是不連續的。所謂的不連續有兩個可能,首先物理地址空間內是有空洞的。其次物理地址空間被分割屬於不同的內存結點。
後者就是NUMA架構。所以在NUMA下都是需要選擇Discontiguous模式。在Discontiguous模式下,在每個內存結點內的物理內存是連續的。


3.3 Sparse Memory Model

  Lwn介紹Sparse模式在這裏
  Discontiguous模式經常和NUMA混淆不清。NUMA並沒有要求每個結點內存一定是連續的。Discontiguous模式也沒有要求必須一定是NUMA。只是因爲兩者都需要多個內存結點,所以在歷史實現上兩者被緊密的捆綁在一起。而且Discontiguouse模式不能支持新的內存熱插拔功能。
  Sparse模式的出現就是爲了解決Discontiguous模式的上述不足。Sparse模式實現與NUMA完全分離,Sparse模式既可以支持NUMA,也可以支持UMA。它不要求NUMA的內存結點一定是連續的,它也允許內存結點的物理內存空間重疊。
  Sparse模式把內存分成一系列大小相同的內存塊。這些內存塊叫做“section”段。每個內存段的的大小的由處理器架構決定的。每個內存section段都可以支持內存熱插拔。每個section內部,物理內存是連續的。


  上述經典的Sparse模式在執行pfn到page的轉換過程需要插入一個section尋址過程。這樣就導致效率不夠高。而且需要在page->flags內存儲太多信息,各種page flag,node id,zone id,現在由增加section id。不同的處理器架構也無法實現一個一致性的算法。基於此,內核又開發了一個Sparse模式的改進版本Sparse_vmemmap。頁框結構的虛擬首地址通過全局指針vmemmap指定。所有的頁框結構虛擬地址是連續的。當發現一個section時,爲其分配頁框結構,然後建立預訂的虛擬地址到實際頁表的映射。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章