日期 | 内核版本 | 架构 | 作者 | 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时,为其分配页框结构,然后建立预订的虚拟地址到实际页表的映射。