☰
page_alloc add_to_free_list
2026/10/22 2:17:11 网站建设 项目流程

add_to_free_list()是__add_to_free_list()的带统计更新的封装版本,用于将一个空闲页块加入伙伴系统的空闲链表,并同步更新free_area的nr_free计数。

核心作用与与__add_to_free_list()的区别

函数操作nr_free计数
__add_to_free_list()仅list_add/list_add_tail调用方负责
add_to_free_list()__add_to_free_list()+ 计数更新自动递增

双下划线前缀__表示“纯物理操作”,而add_to_free_list()是完整封装——加入链表的同时,把zone->free_area[order].nr_free加 1。

典型实现

static inline void add_to_free_list(struct page *page, struct zone *zone, unsigned int order, int migratetype, bool tail) { __add_to_free_list(page, zone, order, migratetype, tail); zone->free_area[order].nr_free++; }

参数解析

参数含义
page页块首页
zone目标 zone
order阶数,决定free_area[order]
migratetype迁移类型,决定free_list[migratetype]
tailtrue尾插(延迟复用),false头插(优先复用)

在释放路径中的位置

__free_one_page()在合并完成后、未被 compaction 捕获时,会调用它把页块加入空闲链表:

if (capc && !compaction_capture(capc, page, order, migratetype)) { set_buddy_order(page, order); add_to_free_list(page, zone, order, migratetype, to_tail); }

迁移类型变更时的nr_free处理

一个容易忽略的细节:当页块从一种迁移类型移到另一种时(如 fallback 偷页、CMA 借用),不能简单地用add_to_free_list(),因为那样会重复增加总数。

move_to_free_list()的操作是“先删后加”:__del_page_from_free_list()会减少旧链表的nr_free,再用__add_to_free_list()(而非add_to_free_list())加回新链表。如果这里误用add_to_free_list(),就会导致该页块的计数被错误地增加。

总结

add_to_free_list()是伙伴系统的空闲链表加入封装:它在__add_to_free_list()完成链表插入的基础上,额外递增zone->free_area[order].nr_free。它被__free_one_page()在释放路径上调用,是“页块进入伙伴系统”时维护空闲计数的标准入口。与它对称的是del_page_from_free_list()(移出 + 递减计数),两者共同保证nr_free的准确性。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询