news 2026/10/5 7:00:13

mm/page_alloc.c

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
mm/page_alloc.c

mm/page_alloc.c是 Linux 内核内存管理子系统中最核心、最庞大的文件之一,主要负责物理内存页的分配与释放,也就是常说的伙伴系统(Buddy System)的实现。它是所有物理内存分配(如alloc_pages、__get_free_pages、kmalloc的底层)的最终落脚点。

下面按功能模块梳理它的主要职责:


1. 伙伴系统(Buddy System)的核心实现

这是该文件最根本的功能:管理物理内存的页框(page frame),以 2 的幂次为单位进行分配和释放。

  • __free_one_page():释放一个页块时,检查其"伙伴"页块是否空闲,若空闲则合并成更大的块,并递归向上合并。

  • __rmqueue()/__rmqueue_smallest()/__rmqueue_fallback():从空闲链表中摘取合适大小的页块;当指定迁移类型(migrate type)没有空闲块时,会从其他迁移类型"偷取"(fallback)。

  • expand():当只需要小块但只有大块空闲时,把大块逐级分裂成小块。

  • __find_buddy_pfn():通过 PFN 异或运算快速找到伙伴页框。

空闲页块按order(阶)组织在free_area[order]中,每个 order 下又按迁移类型(MIGRATE_UNMOVABLE / MOVABLE / RECLAIMABLE 等)分成多个链表,以尽量保持内存的连续性、减少碎片。


2. 每 CPU 页框缓存(Per-CPU Pages, PCP)

为了减少对 zone 锁的争用、提高分配速度:

  • per_cpu_pages/per_cpu_pageset:每个 CPU 每个 zone 维护一个本地页框缓存。

  • rmqueue_pcplist()/rmqueue_bulk():优先从本地缓存分配,缓存空了才批量从伙伴系统补充。

  • free_unref_page()/free_pcppages_bulk():释放时先放入本地缓存,达到高水位再批量归还伙伴系统。

  • 相关水位:pcp->high、pcp->batch、pcp->low。

这是现代内核分配热路径的关键优化。


3. 分配接口(对外 API)

向上层提供多种粒度的物理内存分配函数:

函数说明
alloc_pages()/alloc_pages_node()分配 2^order 个连续物理页,返回struct page *
__get_free_pages()/__get_free_page()返回虚拟地址的分配
get_zeroed_page()分配并清零一页
__alloc_pages()/__alloc_pages_noprof()核心分配函数,含完整的慢路径
__alloc_pages_slowpath()慢路径:唤醒 kswapd、直接回收、内存规整、OOM 等
__alloc_pages_direct_compact()内存规整(compaction)
__alloc_pages_direct_reclaim()直接回收
__alloc_pages_may_oom()触发 OOM killer

GFP 标志(gfp_t)的处理也在这里,例如GFP_KERNEL、GFP_ATOMIC、__GFP_ZERO、__GFP_HIGHMEM等,决定从哪个 zone 分配、能否睡眠/回收。


4. 释放接口

  • free_pages()/__free_pages():释放页块,最终调用__free_one_page()。

  • free_unref_page()/free_pages_prepare():释放前的检查与准备(如检查 page 引用计数、处理PageAnon、PageDirty等)。

  • __put_page()/put_page():减少引用计数,归零时释放。


5. 内存水位与回收触发

  • zone_watermark_ok()/zone_watermark_fast():检查 zone 是否达到水位(WMARK_MIN/LOW/HIGH)。

  • __zone_watermark_ok():考虑保留页、迁移类型后的水位判断。

  • wake_all_kswapds():水位不足时唤醒 kswapd 后台回收。

  • should_reclaim_retry()/should_compact_retry():慢路径中的重试策略。


6. 内存热插拔与初始化

  • free_area_init()/free_area_init_nodes():初始化每个 node/zone 的free_area、zone结构。

  • build_all_zonelists():构建 zone 的分配顺序列表(zonelist)。

  • memmap_init()/memmap_init_range():初始化struct page数组。

  • __init_single_page():初始化单个 page 结构。

  • 与CONFIG_MEMORY_HOTPLUG相关的online_pages()、offline_pages()也在部分版本中涉及。

  • memblock交互:早期内存从 memblock 移交给伙伴系统。


7. 内存碎片化与迁移类型

  • MIGRATE_UNMOVABLE / MOVABLE / RECLAIMABLE / RESERVE / ISOLATE / CMA等迁移类型的维护。

  • set_pageblock_migratetype()/get_pageblock_migratetype():设置/获取页块迁移类型。

  • __rmqueue_fallback():防止碎片化的关键逻辑,避免破坏大块连续内存。

  • find_suitable_fallback():寻找可回退的迁移类型。

  • 与 CMA(连续内存分配器)、__GFP_CMA的交互。


8. 页块隔离与内存规整配合

  • alloc_contig_range()/__alloc_contig_migrate_range():分配连续物理内存(用于 CMA、hugetlb 等)。

  • isolate_freepages()/isolate_migratepages()(部分在compaction.c,但入口在 page_alloc 中协调)。

  • has_unmovable_pages()/is_pageblock_removable_nolock():判断页块是否可移动/可移除。


9. 统计与调试

  • vm_stat//proc/pagetypeinfo//proc/buddyinfo:统计各 order、各迁移类型的空闲页数。

  • __count_zone_vm_events():更新 zone 事件计数。

  • bad_page():检测到损坏的 page 时的报错。

  • dump_page():打印 page 信息用于调试。

  • check_new_page()/free_pages_check():调试模式下检查 page 一致性。

  • setup_per_cpu_pageset():初始化每 CPU 页集。


10. 与其他模块的接口

  • 向SLUB/SLAB(mm/slub.c)提供底层页块。

  • 向vmalloc(mm/vmalloc.c)提供页表页和物理页。

  • 向页表管理(mm/memory.c)提供pte_alloc所需的页。

  • 与kswapd(mm/vmscan.c)配合做页面回收。

  • 与compaction(mm/compaction.c)配合减少碎片。

  • 与CMA(mm/cma.c)配合预留连续内存。

  • 与memory cgroup(mm/memcontrol.c)配合做内存统计和限制。


总结一句话

mm/page_alloc.c是 Linux物理内存页分配器的实现核心,负责伙伴系统的分配/释放、每 CPU 缓存、内存水位判断、慢路径回收与规整、迁移类型与反碎片、内存热插拔初始化,以及向上层提供alloc_pages/free_pages等基础接口。它是整个内核内存管理的"地基"。

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

Python ahr-distributions 包完全指南与实战案例

1. 引言ahr-distributions 是一个专注于概率分布建模与统计计算的 Python 库,它提供了一套统一、简洁的接口,用于定义、采样、拟合和可视化多种常见概率分布。该包特别适合数据分析、机器学习特征工程、蒙特卡洛模拟以及风险分析等场景,帮助开…

作者头像 李华
网站建设 2026/10/5 6:57:54

手把手教你学Simulink——空心杯电机在微型机器人中的极低惯量控制仿真

目录 手把手教你学Simulink——空心杯电机在微型机器人中的极低惯量控制仿真 一、研发目标与系统架构 1.1 研发目标 1.2 系统架构 1.3 接口定义 二、空心杯电机与极低惯量动力学 2.1 电气方程(有刷直流) 2.2 机械方程 2.3 无齿槽效应优势 三、微型机器人传动与非线性…

作者头像 李华
网站建设 2026/10/5 6:54:29

零代码,靠 AI 语音指令搞定零售门店台账管理

我妈的社区超市开了九年,账房三件套:本子、计算器、好记性。上个月我给她搭了套进销存系统,全程半天,零代码。这篇实录从需求到上线全过程,给同样想帮家里数字化的姐妹参考~ 一、老超市的老毛病 1、盘库通宵…

作者头像 李华