linux内存层次关系

Linux中内存管理详解_张孟浩_jay的博客-CSDN博客_linux内存管理

深入理解Linux内存管理

Linux的内存管理是什么,Linux的内存管理详解-电子发烧友网

上图的箭头代表总线,对于UMA(一致性内存访问,Uniform Memory Access),所以cpu都是通过同一根总线访问内存,当cpu和内存过多的时候,总线会成为性能瓶颈。

而NUMA(非一致性内存访问,None Uniform Memory Access)则是各个cpu访问自己的内存节点是通过各自的总线访问。节点之前的内存访问速度,虽然也会很慢,但可以尽量减少节点之间的内存访问。这样就能使得系统总的内存访问速度加快。

UMA模型是指物理内存是连续的,SMP系统中的每个处理器访问各个内存区都是同样快的;而NUMA模型则是指SMP中的每个CPU都有自己的物理内存区,虽然CPU可以访问其他CPU的内存区,但是要比方位自己的内存区慢得多.

物理内存组织

linux中内存分为3个级别。

1、Page:一个页的大小一般为4k,page是内存管理最基本的单位

2、Zone:分为ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM

3、node节点:是对于NUMA的smp系统的,每个cpu都有自己的node,每个node里面又被分为了很多内存域zone,即ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM等。对于UMA,系统中只有一个node

内存节点描述符的定义

typedef struct pglist_data {
	struct zone node_zones[MAX_NR_ZONES];
	struct zonelist node_zonelists[MAX_ZONELISTS];
	int nr_zones;//当前节点管理的内存区数目
#ifdef CONFIG_FLAT_NODE_MEM_MAP	/* means !SPARSEMEM */
	struct page *node_mem_map;//只struct page数组中第一个page,被放置到了全局数组mem_map中
#ifdef CONFIG_MEMCG
	struct page_cgroup *node_page_cgroup;
#endif
#endif
#ifndef CONFIG_NO_BOOTMEM
	struct bootmem_data *bdata;//指向内存的引导程序
#endif
#ifdef CONFIG_MEMORY_HOTPLUG
	spinlock_t node_size_lock;
#endif
	unsigned long node_start_pfn;
	unsigned long node_present_pages; /* total number of physical pages */
	unsigned long node_spanned_pages; /* total size of physical page
					     range, including holes */
	int node_id;
	wait_queue_head_t kswapd_wait;
	wait_queue_head_t pfmemalloc_wait;
	struct task_struct *kswapd;	/* Protected by
					   mem_hotplug_begin/end() */
	int kswapd_max_order;
	enum zone_type classzone_idx;
#ifdef CONFIG_NUMA_BALANCING
	/* Lock serializing the migrate rate limiting window */
	spinlock_t numabalancing_migrate_lock;

	/* Rate limiting time interval */
	unsigned long numabalancing_migrate_next_window;

	/* Number of pages migrated during the rate limiting time interval */
	unsigned long numabalancing_migrate_nr_pages;
#endif
} pg_data_t;

内存区域zone的定义

struct zone {
	............................................
	struct free_area	free_area[MAX_ORDER];
..........................................
	/*
	 * Discontig memory support fields.
	 */
	struct pglist_data	*zone_pgdat;
	/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
	unsigned long		zone_start_pfn;
..................................................
} ____cacheline_internodealigned_in_smp;
struct free_area {
	struct list_head	free_list[MIGRATE_TYPES];
	unsigned long		nr_free;
};

./arch/alpha/mm/numa.c:22:pg_data_t node_data[MAX_NUMNODES];
在arm架构下,没有这个定义。是因为arm并不是NUMA架构??

 对应UMA,内核会定义唯一内存节点contig_page_data

我这个是在linux-3.16\mm\nobootmem.c定义

#ifndef CONFIG_NEED_MULTIPLE_NODES
struct pglist_data __refdata contig_page_data;
EXPORT_SYMBOL(contig_page_data);
#endif

以下内容摘抄自深入理解linux虚拟内存管理(内核版本比较老,上面是linux3.16)

大型机器会将内存分为许多节点,根据节点与处理器"距离"的不同,访问不同的节点会有不同的代价。linux使用struct pglist_data 表示节点(书上说这个结构是一个链表,但是在3.16上,对于NUMA系统,是用一个数组来表示所有节点)。每个节点被分为很多的管理区块,zone。zone的类型一般都是ZONE_DMA,ZONENORMAL和ZONE_HIGHMEM。ZONE_DMA指低端范围的物理内存,是因为某些硬件只能访问最开始的一段物理内存,才诞生了zone_dma。zone_normal部分的内存由内核直接经过线性映射到内核地址空间的最开始的896M部分。zone_highmem是系统预留的可用空间,不可被内核直接映射,需要动态映射。

系统内存最终是被划分为了page,所有的page都存储在一个全局mem_map数组中。通过下图,我最开始以为,一个zone就会有一个mem_map数组。但是书上说该数组是全局变量。难道数组里面包含了系统里面所以的物理内存,部分page属于zone_dma,部分是zone_normal???

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值