内存管理API之__free_pages

void __free_pages(struct page *page, unsigned int order)用于释放从page开始个数为2的order次方的页面
其源码分析如下:
void __free_pages(struct page *page, unsigned int order)
{
	#首先通过put_page_teszero来看page的usage count 是否为0
	#是0的话,才能表示这个page没有人使用,可以释放了.
	if (put_page_testzero(page)) {
		#根据order 是否为0,分两种路径来释放内存
		if (order == 0)
			free_unref_page(page);
		else
			#这个函数会将page 代表的内存是放到伙伴系统中
			__free_pages_ok(page, order);
	}
}
我们重点看看order等于0时候
/*
 * Free a 0-order page
 */
void free_unref_page(struct page *page)
{
	unsigned long flags;
	#根据page得到pfn
	unsigned long pfn = page_to_pfn(page);
	
	if (!free_unref_page_prepare(page, pfn))
		return;

	local_irq_save(flags);
	#将page释放到pcp中,这里pcp的意思是per_cpu_pages,也就是单页的话,不会是放到伙伴系统
	#而是交给个个cpu自己管理
	free_unref_page_commit(page, pfn);
	local_irq_restore(flags);
}
static void free_unref_page_commit(struct page *page, unsigned long pfn)
{
	#得到这个page所在的zone
	struct zone *zone = page_zone(page);
	struct per_cpu_pages *pcp;
	int migratetype;
	#拿到这个页的迁移类型
	migratetype = get_pcppage_migratetype(page);
	#计算vm中free page的个数
	__count_vm_event(PGFREE);

	/*
	 * We only track unmovable, reclaimable and movable on pcp lists.
	 * Free ISOLATE pages back to the allocator because they are being
	 * offlined but treat HIGHATOMIC as movable pages so we can get those
	 * areas back if necessary. Otherwise, we may have to free
	 * excessively into the page allocator
	 */
	 #如果迁移类型大于等于MIGRATE_PCPTYPES,则将迁移类型设置为MIGRATE_MOVABLE
	if (migratetype >= MIGRATE_PCPTYPES) {
		if (unlikely(is_migrate_isolate(migratetype))) {
			free_one_page(zone, page, pfn, 0, migratetype);
			return;
		}
		migratetype = MIGRATE_MOVABLE;
	}
	#得到当前cpu的pcp的指针
	pcp = &this_cpu_ptr(zone->pageset)->pcp;
	#pcp 中的页也是按照迁移类型组成不同的list。所以这里按照迁移类型将页加入到pcp不同的list中
	list_add(&page->lru, &pcp->lists[migratetype]);
	#增加pcp中总的free page的计数
	pcp->count++;
	#pcp中存储的页的个数有个阈值,高于这个阈值的话,则会将多余的页释放到伙伴系统中
	if (pcp->count >= pcp->high) {
		#得到要释放到伙伴系统中页的个数
		unsigned long batch = READ_ONCE(pcp->batch);
		#释放单页到伙伴系统,这里不能通过调用__free_pages 来释放单页,因为__free_pages
		#中会把单页释放到pcp中,造成这里的递归调用
		free_pcppages_bulk(zone, batch, pcp);
		pcp->count -= batch;
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值