首页 > 系统相关 >Linux内存管理之mem_map对象.md

Linux内存管理之mem_map对象.md

时间:2023-04-19 17:13:30浏览次数:48  
标签:node map 0.000000 md mem start pgdat

在linux内核中,所有的物理内存都用struct page结构来描述,这些对象以数组形式存放,而这个数组的地址就是mem_map。内核以节点node为单位,每个node下的物理内存统一管理,也就是说在表示内存node的描述类型struct pglist_data中,有node_mem_map这个成员,其针对平坦型内存进行描述(CONFIG_FLAT_NODE_MEM_MAP),与此相反的是SPARSEMEM,其稀疏性内存描述。

mem_map的作用

mem_map是一个数组,存放了所有的页描述符。一个页对应一个页描述符。

mem_map的定义

/* \linux\mm\memory.c */

#ifndef CONFIG_NEED_MULTIPLE_NODES
/* use the per-pgdat data instead for discontigmem - mbligh */
unsigned long max_mapnr;
struct page *mem_map;

EXPORT_SYMBOL(max_mapnr);
EXPORT_SYMBOL(mem_map);
#endif

dump_stack的输出

[    0.000000] [alloc_node_mem_map 5920] .
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.9.51-1.2 #136
[    0.000000] Hardware name: Broadcom STB (Flattened Device Tree)
[    0.000000] [<c0210710>] (unwind_backtrace) from [<c020bb54>] (show_stack+0x10/0x14)
[    0.000000] [<c020bb54>] (show_stack) from [<c04fc93c>] (dump_stack+0x84/0x98)
[    0.000000] [<c04fc93c>] (dump_stack) from [<c09b6e4c>] (alloc_node_mem_map.constprop.8+0x28/0xd0)
[    0.000000] [<c09b6e4c>] (alloc_node_mem_map.constprop.8) from [<c0e0f10c>] (free_area_init_node+0xf0/0x38c)
[    0.000000] [<c0e0f10c>] (free_area_init_node) from [<c0e065f8>] (bootmem_init+0x16c/0x1b0)
[    0.000000] [<c0e065f8>] (bootmem_init) from [<c0e08ac0>] (paging_init+0xd28/0xd90)
[    0.000000] [<c0e08ac0>] (paging_init) from [<c0e0429c>] (setup_arch+0x61c/0xc24)
[    0.000000] [<c0e0429c>] (setup_arch) from [<c0e009d0>] (start_kernel+0xb8/0x404)
[    0.000000] [<c0e009d0>] (start_kernel) from [<00008090>] (0x8090)

/*
代码调用流程:
start_kernel --> setup_arch --> paging_init --> bootmem_init --> free_area_init_node --> alloc_node_mem_map

由代码调用流程可以看出,mem_map的初始化,是在初始化node时做的。也就是说,mem_map是node下一级的一个概念。
*/

alloc_node_mem_map源码分析

/* \linux\mm\page_alloc.c */
static void __ref alloc_node_mem_map(struct pglist_data *pgdat)
{
	unsigned long __maybe_unused start = 0;
	unsigned long __maybe_unused offset = 0;

    /* 空节点判断 */
	/* Skip empty nodes */
	if (!pgdat->node_spanned_pages)
		return;

#ifdef CONFIG_FLAT_NODE_MEM_MAP

    /* start 是起始页帧号 */
	start = pgdat->node_start_pfn & ~(MAX_ORDER_NR_PAGES - 1);
	offset = pgdat->node_start_pfn - start;

	/* ia64 gets its own node_mem_map, before this, without bootmem */
    /* 如果当前node没有分配node_mem_map, 则分配 */
	if (!pgdat->node_mem_map) {
		unsigned long size, end;
		struct page *map;

		/*
		 * The zone's endpoints aren't required to be MAX_ORDER
		 * aligned but the node_mem_map endpoints must be in order
		 * for the buddy allocator to function correctly.
		 */
        /* end 是终点页帧号 */
		end = pgdat_end_pfn(pgdat);
		end = ALIGN(end, MAX_ORDER_NR_PAGES);

		// (end - start)计算当前节点有多少个page
		size =  (end - start) * sizeof(struct page);
		map = alloc_remap(pgdat->node_id, size);
		if (!map)
			map = memblock_virt_alloc_node_nopanic(size,
							       pgdat->node_id);
		pgdat->node_mem_map = map + offset;
	}
#ifndef CONFIG_NEED_MULTIPLE_NODES
	/*
	 * With no DISCONTIG, the global mem_map is just set as node 0's
	 */
	if (pgdat == NODE_DATA(0)) {
        /* 当前节点是0号节点, 则初始化mem_map*/
		mem_map = NODE_DATA(0)->node_mem_map;
#if defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) || defined(CONFIG_FLATMEM)
		if (page_to_pfn(mem_map) != pgdat->node_start_pfn){
			mem_map -= offset;
			}
#endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
	}
#endif
#endif /* CONFIG_FLAT_NODE_MEM_MAP */
}

/*
这个函数只是给mem_map分配了内存空间,并没有初始化里面的数据
*/

标签:node,map,0.000000,md,mem,start,pgdat
From: https://www.cnblogs.com/linhaostudy/p/17333922.html

相关文章

  • ConcurrentHashMap源码&底层数据结构分析
    ConcurrentHashMap:线程安全的HashMap1.存储结构 ConcurrnetHashMap由很多个Segment组合,而每一个Segment是一个类似于HashMap的结构,所以每一个HashMap的内部可以进行扩容。但是Segment的个数一旦初始化就不能改变,默认Segment的个数是16个,你也可以认为Concu......
  • java 用 Java 将 HashMap 转换为 TreeMap 的程序
    转载自:https://www.moonapi.com/news/24923.html HashMap 是Java1.2以来Java集合的一部分。它提供了以(键、值)对存储数据的JavaMap接口的基本实现。要访问HashMap中的值,必须知道它的键。哈希映射被称为哈希映射,因为它使用哈希技术来存储数据。Java中的树图和抽象......
  • CodeForces - 659C Tanya and Toys (map&模拟)
    CodeForces-659CTanyaandToysTimeLimit: 1000MS MemoryLimit: 262144KB 64bitIOFormat: %I64d&%I64uSubmit StatusDescriptionInBerlandrecentlyanewcollectionoftoyswentonsale.Thiscollectionconsistsof 109 typesof......
  • CodeForces - 367B Sereja ans Anagrams (map)
    CodeForces-367BSerejaansAnagramsTimeLimit: 1000MS MemoryLimit: 262144KB 64bitIOFormat: %I64d&%I64uSubmit StatusDescriptionSerejahastwosequences a and b andnumber p.Sequence a consistsof n integers a1, a......
  • 获取java HashMap 的容量和阈值
      publicstaticvoidmain(String[]args)throwsException{HashMap<Integer,Integer>m=newHashMap<>(9);Class<?>mapType=m.getClass();Fieldthreshold=mapType.getDeclaredField("threshold");......
  • k8s中command、args && dockerfile中entrypoint、cmd之间的比较
    k8s中command、args&&dockerfile中entrypoint、cmd之间的比较标签(空格分隔):K8SDockerfile中ENTRYPOINT,CMD的比较ENTRYPOINT的两种格式:ENTRYPOINT["executable","param1","param2"](exec格式,推荐)ENTRYPOINTcommandparam1param2(shell格式)C......
  • 4月18日set与map的学习
    之前学习过string,list,vector,deque,和两种适配器queue和stack,这些都是线性表的数据结构;而今天学习的map和set他们的底层是二叉搜索树,或者平衡二叉搜索树。首先是set她没有键值对,并且不能出现重复元素,比如当插入两个一时,他只会插入一个一,所以可以用作数组去重。 比如上图当插......
  • 如何计算 目标检测任务的 AP 以及 mAP 指标?
    AP50:50的的意思是IOU的阈值是0.5。先算AP,AP是针对某一类的,表示不同置信度下的PR值的平均,也就是通过不同置信度得到一条PR曲线,曲线下的面积就是AP。这里的置信度是模型输出的条件概率,即是该类的条件下的概率。比如对于persion这一类,模型经过NMS得到一些......
  • emoji.md
    People:bowtie::bowtie:......
  • Redis高级 哈希类型、列表类型、集合类型、有序集合(zset)、慢查询、pipeline与事务
    哈希类型###1---hget,hset,hdelhgetkeyfield#获取hashkey对应的field的value时间复杂度为o(1)hsetkeyfieldvalue#设置hashkey对应的field的value值时间复杂度为o(1)hdelkeyfield#删除hashkey对应的field的值时间复杂度为o(1)#测试hsetuser:1:infoage......