Linux 内核 内存管理物理分配页 ① ( 分区伙伴分配器物理分配页核心函数 __alloc_pages_nodemask | __alloc_pages_nodemask 函数完整源码 )

Posted 韩曙亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux 内核 内存管理物理分配页 ① ( 分区伙伴分配器物理分配页核心函数 __alloc_pages_nodemask | __alloc_pages_nodemask 函数完整源码 )相关的知识,希望对你有一定的参考价值。

文章目录





一、分区伙伴分配器物理分配页核心函数 __alloc_pages_nodemask



Linux 内核中 , " 分区伙伴分配器 " 有多种 物理页分配函数 , 所有的 函数 都会调用 __alloc_pages_nodemask 函数 , 该函数是 物理页分配 的 核心函数 ;

__alloc_pages_nodemask 函数 定义在 Linux 内核源码的 linux-4.12\\mm\\page_alloc.c#4003 位置 , 函数原型如下 :

/*
 * This is the 'heart' of the zoned buddy allocator.
 */
struct page *
__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
			struct zonelist *zonelist, nodemask_t *nodemask)

源码路径 : linux-4.12\\mm\\page_alloc.c#4003





二、__alloc_pages_nodemask 函数完整源码



/*
 * This is the 'heart' of the zoned buddy allocator.
 */
struct page *
__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
			struct zonelist *zonelist, nodemask_t *nodemask)

	struct page *page;
	unsigned int alloc_flags = ALLOC_WMARK_LOW;
	gfp_t alloc_mask = gfp_mask; /* The gfp_t that was actually used for allocation */
	struct alloc_context ac =  ;

	gfp_mask &= gfp_allowed_mask;
	if (!prepare_alloc_pages(gfp_mask, order, zonelist, nodemask, &ac, &alloc_mask, &alloc_flags))
		return NULL;

	finalise_ac(gfp_mask, order, &ac);

	/* First allocation attempt */
	page = get_page_from_freelist(alloc_mask, order, alloc_flags, &ac);
	if (likely(page))
		goto out;

	/*
	 * Apply scoped allocation constraints. This is mainly about GFP_NOFS
	 * resp. GFP_NOIO which has to be inherited for all allocation requests
	 * from a particular context which has been marked by
	 * memalloc_nofs,io_save,restore.
	 */
	alloc_mask = current_gfp_context(gfp_mask);
	ac.spread_dirty_pages = false;

	/*
	 * Restore the original nodemask if it was potentially replaced with
	 * &cpuset_current_mems_allowed to optimize the fast-path attempt.
	 */
	if (unlikely(ac.nodemask != nodemask))
		ac.nodemask = nodemask;

	page = __alloc_pages_slowpath(alloc_mask, order, &ac);

out:
	if (memcg_kmem_enabled() && (gfp_mask & __GFP_ACCOUNT) && page &&
	    unlikely(memcg_kmem_charge(page, gfp_mask, order) != 0)) 
		__free_pages(page, order);
		page = NULL;
	

	if (kmemcheck_enabled && page)
		kmemcheck_pagealloc_alloc(page, order, gfp_mask);

	trace_mm_page_alloc(page, order, alloc_mask, ac.migratetype);

	return page;

源码路径 : linux-4.12\\mm\\page_alloc.c#4003

以上是关于Linux 内核 内存管理物理分配页 ① ( 分区伙伴分配器物理分配页核心函数 __alloc_pages_nodemask | __alloc_pages_nodemask 函数完整源码 )的主要内容,如果未能解决你的问题,请参考以下文章

Linux 内核 内存管理物理分配页 ② ( __alloc_pages_nodemask 函数参数分析 | __alloc_pages_nodemask 函数分配物理页流程 )

Linux 内核 内存管理物理分配页 ⑥ ( get_page_from_freelist 快速路径调用函数源码分析 | 检查内存区域水线 | 判定节点回收 | 判定回收距离 | 回收分配页 )

Linux 内核 内存管理物理分配页 ⑥ ( get_page_from_freelist 快速路径调用函数源码分析 | 检查内存区域水线 | 判定节点回收 | 判定回收距离 | 回收分配页 )

Linux 内核 内存管理物理分配页 ⑨ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | retry 标号代码分析 )

Linux 内核 内存管理物理分配页 ⑧ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | 获取首选内存区域 | 异步回收内存页 | 最低水线也分配 | 直接分配 )

Linux 内核 内存管理物理分配页 ④ ( __alloc_pages_nodemask 函数源码分析 | 快速路径 | 慢速路径 | get_page_from_freelist 源码 )