☰
page_alloc __folio_alloc_noprof
2026/10/14 3:21:25 网站建设 项目流程

__folio_alloc_noprof()是__alloc_pages_noprof()的folio 版本封装。它的核心作用是将伙伴系统返回的struct page *转换为struct folio *,并在必要时执行 THP(透明大页)相关的准备工作。

核心作用与背景

struct folio是 Linux 内存管理引入的新抽象,用于明确表示“一个完整的(可能复合的)页”,替代过去模糊的struct page语义。__folio_alloc_noprof()为需要以 folio 粒度操作内存的调用方提供分配接口。

核心实现

struct folio *__folio_alloc_noprof(gfp_t gfp, unsigned int order, int preferred_nid, nodemask_t *nodemask) { struct page *page; page = __alloc_pages_noprof(gfp | __GFP_COMP, order, preferred_nid, nodemask); if (page && order > 1) prep_transhuge_page(page); return (struct folio *)page; }

关键步骤:

  1. 强制__GFP_COMP:传入gfp | __GFP_COMP,确保分配出的页块被初始化为复合页(compound page)。这是 folio 语义的前提——folio 必须有一个明确的 head page 来承载整个页块的元数据。

  2. 委托__alloc_pages_noprof():实际的物理内存分配完全交给页面分配器主入口。

  3. THP 准备(order > 1):当分配阶数大于 1 时,调用prep_transhuge_page()进行透明大页的初始化。order == 1(两页的 folio)跳过此步骤,因为 deferred list 需要存储在第二个尾页中,而两页 folio 没有足够的尾页空间。

  4. 类型转换返回:将struct page *直接强制转换为struct folio *。在当前实现中,struct folio与struct page是联合体关系,指向首页的指针可以安全地互相转换。

在调用链中的位置

folio_alloc(gfp, order) // 上层宏 └── __folio_alloc_noprof(gfp, order, numa_node_id(), NULL) // ← 这里 ├── __alloc_pages_noprof(gfp | __GFP_COMP, order, ...) // 物理分配 └── prep_transhuge_page(page) // order > 1 时的 THP 准备

总结

__folio_alloc_noprof()是 folio 分配路径的核心实现:它通过__alloc_pages_noprof()获取复合页,对order > 1的分配执行prep_transhuge_page()完成 THP 初始化,最后将首页指针转换为struct folio *返回。__GFP_COMP的强制添加保证了 folio 语义所依赖的复合页结构。

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

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

立即咨询