Linux内存分配alloc_page和__get_free_page详注(伙伴管理系统Buddy)

这篇博客详细解析了Linux内核中Buddy内存管理系统如何通过alloc_page和__get_free_page进行内存分配。虽然两者都涉及Buddy算法,但返回值类型不同,alloc_page返回page结构指针,而__get_free_page返回虚拟地址。它们最终调用到的关键函数是__alloc_pages_nodemask,文章深入探讨了这个函数的工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

alloc_page和__get_free_page都是从Buddy分配页面,只是最终返回值类型不同而已,前者返回page指针,后者返回该page所在的虚拟地址。

两者最终都会调用到核心函数__alloc_pages_nodemask,下面详述该函数的处理流程。


struct page *
__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
			struct zonelist *zonelist, nodemask_t *nodemask)
{
	enum zone_type high_zoneidx = gfp_zone(gfp_mask);
	struct zone *preferred_zone;
	struct page *page;
	int migratetype = allocflags_to_migratetype(gfp_mask);//由于gfp flag和migrate type不是一一对应的关系,在此进行转换

	gfp_mask &= gfp_allowed_mask;

	lockdep_trace_alloc(gfp_mask);

	might_sleep_if(gfp_mask & __GFP_WAIT);//如果此次内存分配可以等待(睡眠),那么再深入判断此task是否可以被调度,如果是将主动schedule

	if (should_fail_alloc_page(gfp_mask, order))//打开CONFIG_FAIL_PAGE_ALLOC调试配置选项时,为分配失败调试做准备
		return NULL;

	/*
	 * Check the zones suitable for the gfp_mask contain at least one
	 * valid zone. It's possible to have an empty zonelist as a result
	 * of GFP_THISNODE and a memoryless node
	 */
	if (unlikely(!zonelist->_zonerefs->zone))
		return NULL;

	get_mems_allowed();//锁定分配策略,防止被修改
	/* The preferred zone is used for statistics later */
	first_zones_zonelist(zonelist, high_zoneidx, nodemask, &preferred_zone);//搜索可用的zone保存在preferred_zone
	if (!preferred_zone) {//如果没有可用的zone,释放分配策略,返回
		put_mems_allowed();
		return NULL;
	}

	/* First allocation attempt */
	//快速路径分配,指定了cpu亲和性和选择高水线区,check zonelist,找到合适的zone,check水线值,
	//如果不满足水线值要求,启动回收机制,最后调用它再buffered_rmqueue在该zone分配内存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值