【Linuxカーネルメモリ管理】物理割り当てページ①(パーティションパートナーアロケータ物理割り当てページコア機能__alloc_pages_nodemask | __alloc_pages_nodemask機能完全ソースコード)





1.パーティションパートナーアロケータの物理割り当てページのコア機能__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

ここに画像の説明を挿入





2.__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_no{fs,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

おすすめ

転載: blog.csdn.net/han1202012/article/details/124389825