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




  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值