news 2026/10/13 10:14:33

page_alloc alloc_pages_bulk_noprof

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
page_alloc alloc_pages_bulk_noprof

alloc_pages_bulk_noprof()是内核提供的批量页面分配接口。它的核心设计目标是减少锁竞争和函数调用开销:通过一次持有 PCP(Per-CPU Pages)锁,连续分配多个页面填充到调用方提供的数组中,而不是反复调用单页分配接口。

函数签名与参数

unsigned long alloc_pages_bulk_noprof(gfp_t gfp, int preferred_nid, nodemask_t *nodemask, int nr_pages, struct page **page_array)
参数含义
gfp分配标志
preferred_nid首选 NUMA 节点
nodemask允许的节点掩码
nr_pages请求分配的页数(数组长度)
page_array输出数组,用于存放分配的页面指针

返回值:实际成功分配的页数。

核心特性与约束

1. 只填充 NULL 槽位

该接口的一个关键语义是:它只填充数组中为 NULL 的槽位,已经非 NULL 的槽位会被跳过。代码中通过nr_populated来跟踪已填充的槽位数量,并在水位检查中使用(nr_pages - nr_populated)来计算剩余需求。

2. 仅支持 order-0

alloc_pages_bulk_noprof()是专门为单页(order-0)分配设计的,不支持高阶分配。如果需要分配高阶页,必须使用__alloc_pages_noprof()等单次分配接口。

3. 不支持 memcg 记账

代码中有一条明确的限制检查:

/* Bulk allocator does not support memcg accounting. */ if (memcg_kmem_online() && (gfp & __GFP_ACCOUNT)) goto failed;

如果内存 cgroup 在线且分配请求带有__GFP_ACCOUNT,批量分配会直接失败,回退到单页分配路径。

4. 单页请求回退

如果nr_pages为 1,或者数组中只剩 1 个槽位需要填充,函数会回退到标准的单页分配接口,因为批量路径的开销不值得为单页付出。

分配策略与水位检查

批量分配的核心优化在于一次性判断 zone 是否有足够的内存满足整批需求,而不是为每一页单独做水位检查。水位检查的标记值计算方式为:

mark = wmark_pages(zone, alloc_flags & ALLOC_WMARK_MASK) + nr_pages - nr_populated;

这里nr_pages - nr_populated是本次调用还需要分配的页数上界,避免重复计算已存在的槽位。

在 PCP 锁下的批量分配循环

水位检查通过后,函数会获取 PCP 锁,然后在一个循环中连续从 PCP 链表取页,直到达到请求数量或 PCP 链表耗尽:

pcp_list = &pcp->lists[order_to_pindex(ac.migratetype, 0)]; while (nr_populated < nr_pages) { page = __rmqueue_pcplist(zone, 0, ac.migratetype, alloc_flags, pcp, pcp_list); if (unlikely(!page)) { /* 如果已经分配了至少一页,可以提前结束 */ if (!nr_populated) { pcp_spin_unlock(pcp); goto failed_irq; } break; } prep_new_page(page, 0, gfp, 0); set_page_refcounted(page); page_array[nr_populated++] = page; }

这个循环的关键点是:只在开始时获取一次 PCP 锁,循环内部不再重复获取锁,大幅减少了锁操作开销。

缺失的追踪钩子(已修复)

在 2026 年 9 月的补丁中,开发者发现批量分配路径遗漏了trace_mm_page_alloc()和kmsan_alloc_page()调用,导致批量分配的页面在 ftrace/BPF/perf 中不可见,KMSAN 的影子内存也未更新。补丁在prep_new_page()和set_page_refcounted()之后添加了这两个钩子,与标准单页分配路径保持一致。

总结

alloc_pages_bulk_noprof()是内核为高性能批量单页分配设计的专用接口。它通过“一次锁、多次分配”的模式减少 PCP 锁竞争,通过“只填充 NULL 槽位”的语义支持增量填充,通过“整批水位检查”避免逐页判断的开销。它的约束也很明确:仅 order-0、不支持 memcg 记账、单页请求回退。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 10:14:06

CentOS 7/8 Docker 安装避坑指南:内核兼容与服务加固实战

1. 这不是“照着官网点几下”的安装指南&#xff0c;而是一份 CentOS 上 Docker 落地的实战手记你搜到的标题里写着“基于官网文档”&#xff0c;但实际操作中&#xff0c;官网那套流程在真实生产环境里经常卡在第三步——不是命令报错&#xff0c;而是系统不认、内核不搭、仓库…

作者头像 李华
网站建设 2026/10/13 10:13:21

开源轻量级工业物联网平台UNIHH-IOT:设备数据采集与可视化实战

年底帮一家中型制造企业做产线数据化改造&#xff0c;折腾了几个月&#xff0c;最大的感触是&#xff1a;市面上能用的物联网平台&#xff0c;要么贵得离谱&#xff0c;要么重得吓人。商用平台按点位收费&#xff0c;一个车间几十台设备一年下来就是一笔不小的开支&#xff1b;…

作者头像 李华
网站建设 2026/10/13 10:11:35

零基础用AI造产品:7天跑通变现闭环的实战方法论

1. 这不是“学AI”&#xff0c;而是用AI造产品&#xff1a;一个真实可跑通的变现闭环“零基础 AI 编程指南&#xff1a;用 AI 开发产品&#xff0c;落地变现完整教程”——这个标题里藏着三个被严重低估的关键信号&#xff1a;零基础不是指“完全不懂电脑”&#xff0c;而是指不…

作者头像 李华
网站建设 2026/10/13 10:11:27

6.3.5 CRL 过期了,但证书本身是好的

6.3.4 测的是 CRL 取不到&#xff0c;这条测的是 CRL 取到了&#xff0c;但它是旧的。CRL 文件本身带有效期&#xff0c;nextUpdate 一过就失效。设备读到一个已经过期的 CRL&#xff0c;该怎么办&#xff1f; 标准给的答案是宽容&#xff1a;报 Warning: CRL expired&#xff…

作者头像 李华
网站建设 2026/10/13 10:11:24

STM32下uC/OS-III系统实战指南:从任务管理到多任务同步全解析

1. OS概述 在嵌入式开发中,随着系统功能的日益复杂,传统的裸机编程方式逐渐暴露出局限性。当多个任务需要并发执行、实时响应要求较高时,引入操作系统(OS)成为必然选择。操作系统在嵌入式领域的引入,主要目的包括: 任务调度管理:操作系统能够合理分配 CPU 时间,让多个…

作者头像 李华
网站建设 2026/10/13 10:10:55

煤层气THM耦合模拟:渗透率孔隙度模型与现场应用要点

煤层气项目的现场数据&#xff0c;是最会骗人的。我前几年在某区块做开发方案时&#xff0c;实验室测出来的岩心渗透率是0.5毫达西&#xff0c;按这个数建模型&#xff0c;预测的单井产气量能到每天两千方。结果打下去一压裂一排采&#xff0c;实际稳定产气量连零头都不到&…

作者头像 李华