内存管理-伙伴系统:__find_buddy_pfn 函数解析与伙伴查找机制

张开发
2026/4/10 17:18:46 15 分钟阅读

分享文章

内存管理-伙伴系统:__find_buddy_pfn 函数解析与伙伴查找机制
内存管理-伙伴系统__find_buddy_pfn 函数解析与伙伴查找机制文章目录内存管理-伙伴系统__find_buddy_pfn 函数解析与伙伴查找机制伙伴系统合并机制概述__find_buddy_pfn 函数解析伙伴系统初始化时的块分配规则实例分析合并场景补充总结伙伴系统合并机制概述伙伴系统的核心价值在于通过空闲块的合并减少内存碎片而合并的前提是精准定位当前块的“伙伴”。__find_buddy_pfn函数的作用正是计算给定页帧号Page Frame Number, pfn在指定阶order下的伙伴页帧号。仅当伙伴块与当前块阶数相同且均为空闲状态时才会触发后续的合并逻辑。linux-5.10.202/mm/page_alloc.c:1018buddy_pfn__find_buddy_pfn(pfn,order);// 相邻的伙伴块按照 ^ (1 order) 计算__find_buddy_pfn 函数解析__find_buddy_pfn是一个静态内联函数通过位异或运算实现伙伴页帧号的快速计算其源码与注释如下linux-5.10.202/mm/internal.h:156/* * Locate the struct page for both the matching buddy in our * pair (buddy1) and the combined O(n1) page they form (page). * * 1) Any buddy B1 will have an order O twin B2 which satisfies * the following equation: * B2 B1 ^ (1 O) * For example, if the starting buddy (buddy2) is #8 its order * 1 buddy is #10: * B2 8 ^ (1 1) 8 ^ 2 10 * * 2) Any buddy B will have an order O1 parent P which * satisfies the following equation: * P B ~(1 O) * * Assumption: *_mem_map is contiguous at least up to MAX_ORDER */staticinlineunsignedlong__find_buddy_pfn(unsignedlongpage_pfn,unsignedintorder){returnpage_pfn^(1order);}以 pfn 8二进制1000、order 1 为例该块包含连续 2 个页pfn 8 和 9。通过位异或运算8 ^ (1 1)得到伙伴页帧号为 10对应块包含 pfn 10 和 11。后续逻辑会验证伙伴块是否处于相同阶且空闲若满足则合并为 order 2 的块。伙伴系统初始化时的块分配规则伙伴系统初始化通过__free_pages_memory函数将内存块按阶对齐规则加入空闲链表确保每个块的起始 pfn 是2^order的整数倍。源码如下linux-5.10.202/mm/memblock.c:1900staticvoid__init__free_pages_memory(unsignedlongstart,unsignedlongend)// 伙伴系统初始化会按照 page 的 pfn 按阶存放 每个阶存档的page地址一定是 2**n 对齐{intorder;while(startend){ordermin(MAX_ORDER-1UL,__ffs(start));// ffs 第一个有 1 的 bit 位置 - 1相当于根据 pfn 地址确定 orderwhile(start(1ULorder)end)// 和 1912 行的 start (1UL order); 有联系如果有连续大块放到对应 orderorder--;memblock_free_pages(pfn_to_page(start),start,order);// 加入到伙伴系统start(1ULorder);}}函数逻辑拆解__ffs(start)返回start二进制表示中第一个置 1 位的位置从 0 计数用于确定初始阶数通过内层循环动态降低阶数确保块大小(1 order)不超过剩余内存范围start到end调用memblock_free_pages将对齐后的块加入伙伴系统并更新start指针处理下一段内存。实例分析以 pfn 1 到 13共 12 个连续页为例展示初始化时的块分配逻辑pfnhex__ffs加入到伙伴的阶解释11001 (1 0) 13210112 (1 1) 133111跳过2 (1 1)4100224 (1 2) 1351012跳过4 (1 2)61102跳过4 (1 2)71112跳过4 (1 2)合并场景补充若 pfn 3 变为 0 阶并释放其伙伴为 pfn 2计算3 ^ (1 0) 2二者可合并为 1 阶块同理pfn 4 和 5 在 0 阶互为伙伴合并为 1 阶后可与 pfn 6-7 组成的 1 阶块进一步合并为 2 阶块计算4 ^ (1 1) 6。总结伙伴查找核心机制__find_buddy_pfn通过page_pfn ^ (1 order)位异或运算快速定位物理地址连续且对齐的伙伴页帧号是伙伴系统合并逻辑的基础。初始化对齐规则__free_pages_memory利用__ffs确定初始阶数动态调整以适配内存范围确保每个块按2^order对齐加入伙伴系统为后续合并创造条件。合并逻辑约束仅当伙伴块阶数相同且均为空闲时才会触发合并通过逐步提升阶数有效减少内存碎片。

更多文章