ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

page_alloc bad_range

page_alloc bad_range 调试用的检查函数用于验证某个page是否真的属于某个zone的合法范围。它配合page_outside_zone_boundaries()使用。一、函数签名static bool __maybe_unused bad_range(struct zone *zone, struct page *page)参数参数类型含义zonestruct zone *目标 zonepagestruct page *待检查的页返回值booltrue表示这个 page 不在 zone 的合法范围内即异常/坏范围false表示正常。关键属性1.static文件内私有只在page_alloc.c内部使用。典型的调试辅助函数。2.__maybe_unused告诉编译器即使这个函数没被使用也不要报警告。为什么可能没被使用因为bad_range()的调用点通常包在条件编译或调试宏里#ifdef CONFIG_DEBUG_VM if (bad_range(zone, page)) ... #endif或VM_BUG_ON_PAGE(bad_range(zone, page), page);当CONFIG_DEBUG_VM未开启时VM_BUG_ON_PAGE被编译掉bad_range()可能就没有任何调用者如果没有__maybe_unused编译器会警告defined but not used。所以这个属性是为配置灵活性服务的。二、bad_range()的作用语义判断page是否不属于zone。返回true表示坏。典型实现补充通常它只是对page_outside_zone_boundaries()的包装再加上一些额外检查static bool __maybe_unused bad_range(struct zone *zone, struct page *page) { if (page_outside_zone_boundaries(zone, page)) return true; if (!zone_spans_pfn(zone, page_to_pfn(page))) return true; return false; }或者更简单static bool __maybe_unused bad_range(struct zone *zone, struct page *page) { return page_outside_zone_boundaries(zone, page); }具体实现随内核版本但核心是检查 page 是否落在 zone 的 pfn 范围内。与page_outside_zone_boundaries()的关系前一个函数static int page_outside_zone_boundaries(struct zone *zone, struct page *page)检查page的 pfn 是否超出zone 的[zone_start_pfn, zone_end_pfn)范围。返回int0 / 非 0。bad_range()把结果转成bool可能再加上其他一致性检查。命名更直观坏范围。两者都是调试辅助用于捕获传入了错误的 zone/page 组合这类 bug。三、为什么需要这类检查在内存管理代码中zone 和 page 必须匹配每个struct page属于且仅属于一个 zone由它的 pfn 决定。很多函数接收(zone, page)参数隐含假设page属于zone。如果调用方传错如把 A zone 的 page 传给 B zone 的函数会导致统计错乱链表操作错误内存损坏难以调试的崩溃。bad_range()就是在调试配置下主动检测这种错误尽早BUG或WARN而不是等到问题扩散。典型调用点static inline void __free_one_page(struct page *page, unsigned long pfn, struct zone *zone, ...) { VM_BUG_ON_PAGE(bad_range(zone, page), page); ... }释放页时检查page是否真的属于zone。分配、合并、统计等路径也可能用。四、__maybe_unused与调试配置的关系CONFIG_DEBUG_VM开 / 关配置VM_BUG_ON_PAGE(bad_range(...))bad_range()是否被调用CONFIG_DEBUG_VMy展开为真实检查✅ 有调用者CONFIG_DEBUG_VMn编译为空❌ 无调用者未开启时函数定义了但没人用。__maybe_unused让编译器不报 warning。这是内核中调试辅助函数的常见模式static bool __maybe_unused some_debug_check(...)为什么还保留函数定义开启CONFIG_DEBUG_VM时直接可用无需改代码。保持代码结构清晰调试逻辑独立成函数而非散落在各处。编译器在未使用时可能仍会优化掉函数体若static且无引用所以不占运行期空间。五、与前面内容的呼应前面出现过的这里的关联page_outside_zone_boundaries()bad_range()通常调用它做核心检查VM_BUG_ON_PAGE()bad_range()的典型调用包装CONFIG_DEBUG_VM决定bad_range()是否被调用__maybe_unused避免未开启调试时的 unused 警告zone_spans_pfn()前面get_pfnblock_bitmap_bitidx()里用过这里也可能用zone-zone_start_pfn/zone_end_pfnzone 范围的基础调用链__free_one_page() / 其他分配释放路径 └── VM_BUG_ON_PAGE(bad_range(zone, page), page) └── bad_range(zone, page) └── page_outside_zone_boundaries(zone, page) └── 检查 pfn 是否在 [zone_start_pfn, zone_end_pfn)
返回列表