news 2026/10/15 10:37:27

page_alloc per_cpu_pages_init

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
page_alloc per_cpu_pages_init

启动阶段的 PCP(Per-CPU Pages)初始化接口、boot pageset 的常量,以及每 CPU 的 boot 页集和统计结构。


一、per_cpu_pages_init()前置声明

static void per_cpu_pages_init(struct per_cpu_pages *pcp, struct per_cpu_zonestat *pzstats);
  • 前置声明:告诉编译器这个函数存在,实际定义在后面。

  • 作用:初始化一个per_cpu_pages结构及其配套的per_cpu_zonestat。

  • static:文件内私有。

  • 调用时机:在 CPU 上线、zone 初始化时被调用,用于建立该 CPU 对某 zone 的 PCP 缓存。


二、boot pageset 的常量

/* These effectively disable the pcplists in the boot pageset completely */ #define BOOT_PAGESET_HIGH 0 #define BOOT_PAGESET_BATCH 1

作用

这两个常量用于配置启动阶段的 PCP 缓存,使其实际上被禁用。

为什么启动阶段要禁用 PCP?

  • 启动早期,内存管理子系统还没完全初始化好:

    • PCP 的批量补充/归还机制依赖伙伴系统、水位判断等;

    • 如果此时启用 PCP 缓存,可能因缓存页未及时归还而导致水位判断失准,甚至死锁。

  • 禁用方式:

    • HIGH = 0:高水位为 0,意味着 PCP 缓存中不能有任何页——一旦有页就立即触发批量归还。

    • BATCH = 1:批量大小为 1,每次只补充/归还一页。

  • 效果:PCP形同虚设,分配/释放几乎直接走伙伴系统,行为最简单、最安全。

与正常运行期的对比

阶段pcp->highpcp->batchPCP 行为
启动(boot pageset)01禁用,直接走伙伴系统
正常运行动态计算(几十~几百)动态计算缓存页,减少锁竞争

三、boot pageset 的 per-CPU 结构

static DEFINE_PER_CPU(struct per_cpu_pages, boot_pageset); static DEFINE_PER_CPU(struct per_cpu_zonestat, boot_zonestats);

1.boot_pageset

  • 每 CPU 一个struct per_cpu_pages,是启动阶段使用的 PCP 缓存。

  • 每个 zone 在初始化时,会先指向这个 boot pageset,等真正初始化时再切换到分配好的 pageset。

  • 用DEFINE_PER_CPU定义,每 CPU 一份。

2.boot_zonestats

  • 每 CPU 一个struct per_cpu_zonestat,是启动阶段的 zone 统计结构。

  • per_cpu_zonestat保存 per-CPU 的 zone 统计(如NR_FREE_PAGES的差分值、NR_ZONE_*计数等)。

  • 同样每 CPU 一份。

为什么需要单独的 boot 版本?

  • 启动顺序问题:zone->per_cpu_pageset需要指向有效的 per-CPU 结构,但动态分配的 pageset 在内存子系统完全就绪前可能还不可用。

  • 解决方案:先用静态定义的boot_pageset/boot_zonestats作为占位,让 zone 能正常工作;等setup_per_cpu_pageset()执行时,再切换到动态分配的正式 pageset。

  • 静态定义:DEFINE_PER_CPU在编译期分配空间,不依赖运行时内存分配,启动早期即可用。

切换流程(示意)

/* 启动早期:zone 指向 boot pageset */ zone->per_cpu_pageset = &boot_pageset; /* 稍后 setup_per_cpu_pageset():切换到正式 pageset */ for_each_online_cpu(cpu) { pcp = per_cpu_ptr(zone->per_cpu_pageset, cpu); per_cpu_pages_init(pcp, pzstats); // 用正式 pageset 重新初始化 }

四、与前面内容的呼应

前面出现过的这里的关联
struct per_cpu_pagesboot pageset 的类型
struct per_cpu_zonestatboot zonestats 的类型
pcp->high/pcp->batch被BOOT_PAGESET_HIGH/BOOT_PAGESET_BATCH控制
free_pcppages_bulk()高水位为 0 时会频繁触发,但启动期 batch=1 影响小
drain_pages()/drain_all_pages()PCP 排空机制,与 pageset 初始化配套
setup_per_cpu_pageset()切换到正式 pageset 的初始化函数

五、小结表

项说明
per_cpu_pages_init()前置声明,初始化 PCP + zonestat
BOOT_PAGESET_HIGH = 0启动阶段 PCP 高水位为 0,禁用缓存
BOOT_PAGESET_BATCH = 1启动阶段批量大小为 1
boot_pageset每 CPU 的启动阶段 PCP 结构
boot_zonestats每 CPU 的启动阶段 zone 统计结构
设计意图启动早期用静态占位结构,避免依赖动态分配;等初始化完成再切换到正式 pageset

一句话总结

这段代码为启动阶段的 PCP 机制做准备:per_cpu_pages_init()是初始化接口;BOOT_PAGESET_HIGH=0/BOOT_PAGESET_BATCH=1使 boot pageset 的 PCP 缓存形同禁用,分配/释放几乎直接走伙伴系统,避免启动早期的不稳定;

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

常见DDL自动处理,特殊规则人工补充:KFS异构同步的实现边界

在某大型医院的数据同步项目中,260条同步链路同时运行,源端涉及Oracle、MySQL、SQL Server、KES V8R6、Vastbase等10多种数据库,并持续向目标库汇聚数据。 在这样的环境里,把数据同步过去并不难。真正让链路“卡住”的&#xff0c…

作者头像 李华
网站建设 2026/10/15 10:36:41

impeccable:AI前端代码质量闸门与CLI工作流实践

1. 从"impeccable"这个词说起:一个被低估的前端质量信号第一次看到"impeccable"作为项目名,我下意识去查了这个词的本义——无可挑剔的、零瑕疵的。放在前端设计和 AI coding agents 的语境里,这个词其实点出了一个很具体…

作者头像 李华
网站建设 2026/10/15 10:36:29

AI绘画提示词中的黄金锚点:ponytail视觉控制原理与实战

项目标题“ponytail”本身是一个英文单词,直译为“马尾辫”,在日常语境中指一种将头发束于脑后、形似马尾的常见发型。但作为当前网络热词单独出现,且无上下文、无配图、无正文描述,其传播动因必然脱离了基础发型定义——它已悄然…

作者头像 李华
网站建设 2026/10/15 10:36:27

技术手册PDF文本抽取实战:从解析库到结构还原

简介:《BOOK OF WISDOM 2》(智慧之书第二册)是一份围绕“现实本质与心智关系”展开的英文电子文档,适合对意识哲学、形而上思考以及光与物质交互关系感兴趣的读者作为扩展研读材料。文档并非循序渐进的技术教程,而是采…

作者头像 李华
网站建设 2026/10/15 10:35:50

分光计测三棱镜顶角实验报告:自准法与反射法完整拆解

简介:这份大学物理实验报告文档面向理工科学生及物理实验初学者,聚焦分光计的结构认知与操作训练,重点解决三棱镜顶角测量中的仪器调整与数据处理问题。资源包内含1个doc文件,大小约152KB,内容涵盖实验目的、仪器说明、…

作者头像 李华
网站建设 2026/10/15 10:35:48

带你速通Cursor核心能力:Agent、MCP与Rules配置到TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华