资讯动态

page_alloc task_capc

发布时间:2026/10/8 19:39:52 来源:尧图企业网站定制
task_capc()是页面分配器与内存规整Compaction之间的关键“捕获接口”。它的作用是判断当前任务是否正在进行直接内存规整并且需要从指定的 zone 中“捕获”一个刚被释放的页面。核心目的解决规整的竞态问题内存规整Compaction天生存在竞态它在迁移页面、试图凑出连续的大块内存时一个被释放的、合适的页面可能立刻被其他并行任务抢走分配掉导致规整白忙一场。capture_control机制就是为此设计的在直接规整的慢路径中一旦有页面被释放立即“捕获”并隔离它避免被其他分配请求抢走从而避免重复扫描提升规整效率。函数签名与逻辑static inline struct capture_control *task_capc(struct zone *zone)参数zone当前正在释放页面的区域zone。返回值如果满足捕获条件返回指向当前任务capture_control结构的指针否则返回NULL。它的典型实现如下static inline struct capture_control *task_capc(struct zone *zone) { struct capture_control *capc current-capture_control; return unlikely(capc) !(current-flags PF_KTHREAD) !capc-page capc-cc-zone zone ? capc : NULL; }逐条件解析unlikely(capc)这是一个热路径优化。绝大多数页面释放时并没有进行捕获所以这个检查被标记为“不太可能”让编译器把后续的判断代码移出热点路径。!(current-flags PF_KTHREAD)排除内核线程。捕获机制只服务于用户任务发起的直接规整内核线程不参与。!capc-page确保捕获槽位是空的。如果capc-page已经有值说明当前任务已经捕获到了一个页面不需要再捕获了。capc-cc-zone zonezone 必须匹配。只有正在释放的页面属于规整操作关注的 zone捕获才有意义。在释放路径中的使用这个函数在__free_one_page()伙伴系统页面释放的核心函数中被调用static inline void __free_one_page(...) { struct capture_control *capc task_capc(zone); ... while (order max_order) { if (compaction_capture(capc, page, order, migratetype)) { __mod_zone_freepage_state(zone, -(1 order), migratetype); return; // 页面被捕获不再放回伙伴系统 } ... } ... }一旦task_capc()返回有效的capc且后续的compaction_capture()成功捕获该页面这个页面就不会进入伙伴系统的空闲链表而是被直接交给等待中的规整操作使用。一个重要的历史修复中断上下文的安全早期版本曾因中断上下文出现问题一个任务在设置current-capture_control和初始化其内部指针capc-cc之间被中断中断处理程序若恰好释放页面task_capc()会读到未完全初始化的结构导致空指针解引用崩溃。修复方案包括在设置current-capture_control前使用barrier()确保结构体初始化完成并用WRITE_ONCE()防止存储撕裂。或者更保守地让task_capc()只在该任务确实处于规整上下文中时才返回有效指针。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑