尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
page_alloc account_freepages
空闲页计数与统计更新的辅助函数。它在页被释放回伙伴系统或从伙伴系统取出时调用负责更新 zone 的空闲页计数、迁移类型统计、内存事件等。一、函数签名static inline void account_freepages(struct zone *zone, int nr_pages, int migratetype)参数参数类型含义zonestruct zone *目标 zonenr_pagesint页数变化量可正可负migratetypeint迁移类型用于更新对应统计返回值void。static inline文件内私有 强制/建议内联。在伙伴系统的分配/释放热路径上频繁调用必须零开销。二、nr_pages的符号约定关键nr_pages可正可负。场景nr_pages含义释放页正数空闲页增加分配页负数空闲页减少释放account_freepages(zone, 1 order, migratetype)→ zone 空闲页 2^order。分配account_freepages(zone, -(1 order), migratetype)→ zone 空闲页 -2^order。为什么统一用带符号的int一个函数同时处理增加和减少避免写两个函数。调用方只需传正/负值逻辑简单。内部按符号更新各项统计。三、典型实现static inline void account_freepages(struct zone *zone, int nr_pages, int migratetype) { /* * 1. 更新 zone 的空闲页计数 * zone-free_area 各阶空闲页总数 */ __mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages); /* * 2. 更新 zone 的按迁移类型空闲页统计 * 某些内核版本用 NR_FREE_CMA_PAGES 等独立计数 */ if (is_migrate_cma(migratetype)) __mod_zone_page_state(zone, NR_FREE_CMA_PAGES, nr_pages); /* * 3. 更新全局 VM 事件计数 * 如 PGALLOC页分配、PGFREE页释放 */ __count_zid_vm_events(PGALLOC, zone_idx(zone), nr_pages); /* 或根据符号区分 PGALLOC / PGFREE */ }逐步说明1. 更新 zone 空闲页计数__mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages);NR_FREE_PAGESzone 的空闲页总数per-CPU 缓存 伙伴系统。__mod_zone_page_state()以per-CPU 差分方式更新避免频繁加锁。这是最核心的更新zone-vm_stat[NR_FREE_PAGES] nr_pages。2. 更新迁移类型相关统计if (is_migrate_cma(migratetype)) __mod_zone_page_state(zone, NR_FREE_CMA_PAGES, nr_pages);CMA 页有独立计数NR_FREE_CMA_PAGES用于判断 CMA 区域是否充足。其他迁移类型可能共用NR_FREE_PAGES不单独统计。某些版本还会更新NR_FREE_PAGES之外的 per-migratetype 计数如/proc/pagetypeinfo的数据来源。3. 更新 VM 事件计数__count_zid_vm_events(PGALLOC, zone_idx(zone), nr_pages);PGALLOC页分配事件。__count_zid_vm_events()按 zone 统计事件。释放时可能记PGFREE分配时记PGALLOC——具体实现可能用符号判断。这些计数用于/proc/vmstat展示。4. 与水位、回收的联动更新NR_FREE_PAGES后水位判断zone_watermark_ok()才能正确工作。如果空闲页低于水位可能触发 kswapd 唤醒。所以account_freepages()是内存压力感知的基础。四、与__mod_zone_freepage_state()的关系在伙伴系统代码里常会看到另一个函数static inline void __mod_zone_freepage_state(struct zone *zone, int nr_pages, int migratetype) { __mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages); if (is_migrate_cma(migratetype)) __mod_zone_page_state(zone, NR_FREE_CMA_PAGES, nr_pages); }__mod_zone_freepage_state()是更早/更常见的名字功能与account_freepages()类似。不同内核版本可能用__mod_zone_freepage_state()或重命名为account_freepages()并扩展功能加 VM 事件统计。语义一致更新 zone 空闲页计数含 CMA 特殊处理。使用示例__free_one_page()static inline void __free_one_page(struct page *page, unsigned long pfn, struct zone *zone, unsigned int order, int migratetype, fpi_t fpi_flags) { ... if (compaction_capture(...)) return; /* 被捕获不计入常规空闲 */ set_buddy_order(page, order); list_add(page-lru, zone-free_area[order].free_list[migratetype]); /* 更新统计 */ account_freepages(zone, 1 order, migratetype); }使用示例分配路径static inline void expand(struct zone *zone, struct page *page, int low, int high, int migratetype) { ... /* 分裂大块剩余部分放回 */ set_buddy_order(page[size], high); list_add(page[size].lru, zone-free_area[high].free_list[migratetype]); account_freepages(zone, 1 high, migratetype); }五、为什么要用 per-CPU 差分__mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages);zone 的统计是全局的但更新非常频繁每次分配/释放。如果每次都加锁改全局计数器竞争严重、性能差。内核用per-CPU 差分每个 CPU 维护自己的差分值更新时只改本地差分无锁读全局值时把所有 CPU 差分汇总。这就是__mod_zone_page_state比zone_page_state_add直接改快的原因。代价读到的值可能有轻微延迟/不一致但对统计/水位判断足够。六、与前面内容的呼应前面出现过的这里的关联__free_one_page()释放路径调用account_freepages()expand()/__rmqueue_smallest()分配/分裂路径调用set_buddy_order()标记 Buddy 状态后调用统计compaction_capture()捕获的页不计入统计提前 returnMIGRATE_CMA/is_migrate_cma()特殊处理 CMA 计数zone_watermark_ok()依赖NR_FREE_PAGES本函数更新它NR_FREE_PAGES/NR_FREE_CMA_PAGES本函数更新的计数项per-CPU 差分__mod_zone_page_state的实现方式调用链__free_one_page() / expand() / __rmqueue_smallest() └── account_freepages(zone, ±nr_pages, migratetype) ├── __mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages) // 核心 ├── if (is_migrate_cma) __mod_zone_page_state(..., NR_FREE_CMA_PAGES, ...) └── __count_zid_vm_events(PGALLOC/PGFREE, zone_idx(zone), ...)七、小结表项说明函数名account_freepages作用更新 zone 空闲页计数、迁移类型统计、VM 事件参数zone目标 zone参数nr_pages页数变化量正释放/增加负分配/减少参数migratetype迁移类型用于 CMA 等特殊统计返回值void可见性static inline热路径核心操作__mod_zone_page_state(NR_FREE_PAGES) CMA 特殊 VM 事件别名/前身__mod_zone_freepage_state()实现方式per-CPU 差分避免全局锁竞争调用点__free_one_page()、expand()、__rmqueue_smallest()等一句话总结account_freepages()是伙伴系统分配/释放热路径上的统计更新函数根据带符号的nr_pages正释放、负分配更新 zone 的NR_FREE_PAGES及 CMA 的NR_FREE_CMA_PAGES和 VM 事件计数采用 per-CPU 差分避免锁竞争它是水位判断、内存压力感知和/proc统计的基础与set_buddy_order()在释放路径上紧邻调用。
RELATED

相关推荐

多线程 2

多线程 2

1. Thread 类、常见方法 1.1 常用构造方法方法说明Thread()创建线程对象Thread( Runnable target)使用 Runnable 对象创建线程对象Thread(String name)创建线程对象并命名Thread( Runnable target ,String name)使用 Runnable 对象创建线程对象,并命名1.…

📅 2026/10/8 8:25:26
【八个月网安课程】第九周·周四:指纹识别与 Google Hacking——whatweb、wappalyzer 与搜索引擎语法

【八个月网安课程】第九周·周四:指纹识别与 Google Hacking——whatweb、wappalyzer 与搜索引擎语法

今天将学会如何在不见面、不扫描的情况下,通过识别目标网站的技术栈和利用搜索引擎获取敏感信息,将信息收集提升到更高维度。这些技巧是渗透测试标准流程中“信息收集”阶段的核心组成部分,能帮你绘制出目标的完整技术画像,发现隐…

📅 2026/10/8 8:20:26
Orca并行代理管理:开源ADE的调度、协作与故障恢复机制解析

Orca并行代理管理:开源ADE的调度、协作与故障恢复机制解析

最近圈子里一直在聊 AI Agent,但大部分开源项目都停留在"单代理跑通一个流程"的阶段。真正到了生产环境,任务一多、流程一变长、代理之间还要协作的时候,线性串行执行根本扛不住。我一直在找能解决这个问题的开源方案,直…

📅 2026/10/8 8:20:26
MORE NEWS

更多资讯

📰

风光储互补调度模型:废弃矿井抽蓄与电池储能协同优化

做过新能源消纳或者源网荷储协同研究的人,应该都遇到过这么一个问题:配了风光、配了储能,但调度策略还在靠经验拍脑袋。白天光伏大发的时候把电池充满,晚上风电出力上来了,电池却早就没电了;大电网负荷尖峰…

📰

梯级水光互补系统期望电量最大化短期优化调度模型与Python复现

前阵子接到一个论文复现的活,课题名称很长:梯级水光互补系统最大化可消纳电量期望短期优化调度模型(Python代码实现)。当时一看就明白,这是典型的随机优化类电力调度问题,核心不外乎在光伏出力的不确定性下…

📰

claude-mem:为Claude跨会话记忆装上外挂笔记本

如果你经常用 Claude 干活,你大概率遇到过这种情况:上一个对话里你刚告诉它“这个项目的构建命令是 make build,测试用 make test”,下一个新对话它又一问三不知,像从来没有见过你一样。Claude 本身没有跨会话记忆&…

📰

Ashooter激光对中仪全球销量第一的秘诀

AS500四合一激光对中仪的核心优势,就是把“对中、振动、红外、听诊”四个功能集成到一台手持设备里,一机搞定旋转设备的全流程诊断。‌‌AS500不仅是全球销量第一,更是中国市场份额第一的激光对中仪⚙️ ASHOOTER四大功能集成,一台…

📰

钢铁涨价成仓储自动化催化剂:成本精算下的行业洗牌与ROI重构

最近这段时间,做仓储自动化解决方案的朋友普遍有一个感觉:客户的电话突然好打了。以前约项目,人家一上来就是“你们设备贵,先放着,我们考虑考虑”,报价单发过去基本石沉大海。现在反而是甲方主动翻出半年前…

📰

路由策略与策略路由实验:概念、配置与排障实战

做路由策略实验的人很多,但真正把“路由策略”和“策略路由”掰扯清楚、能把实验做到位的人,说实话不多。我去年做一次割接演练时,就因为在"过滤路由"和"引导流量"这两个需求上选错了工具,结果明明是同一张拓…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬