资讯动态

slub check_slab

发布时间:2026/10/30 2:30:50 来源:尧图企业网站定制
check_slab()是 SLUB 调试中校验 slab 页级基本状态的函数位于对象级检查check_object之前先确认 slab 页本身的结构字段是否合理。一、函数签名static int check_slab(struct kmem_cache *s, struct slab *slab)参数含义s缓存slab要校验的 slab 页返回int1 表示 slab 基本状态正常0 表示发现异常。二、典型实现static int check_slab(struct kmem_cache *s, struct slab *slab) { int maxobj; if (!virt_addr_valid(slab)) { slab_err(s, slab, Not a valid slab page); return 0; } if (!PageSlab(slab_page(slab))) { slab_err(s, slab, Not a slab page); return 0; } maxobj (PAGE_SIZE oo_order(s-oo)) / s-size; if (slab-objects maxobj) { slab_err(s, slab, objects %u max %u, slab-objects, maxobj); return 0; } if (slab-inuse slab-objects) { slab_err(s, slab, inuse %u max %u, slab-inuse, slab-objects); return 0; } if (slab-objects 0 slab-inuse ! 0) { slab_err(s, slab, inuse %u, but no objects, slab-inuse); return 0; } return 1; }逻辑分几层1. 地址有效性if (!virt_addr_valid(slab)) { slab_err(s, slab, Not a valid slab page); return 0; }virt_addr_valid(slab)检查slab指针是否是合法内核虚拟地址。防止后续字段访问触发缺页或访问非法地址。失败则报告Not a valid slab page。2. 确实是 slab 页if (!PageSlab(slab_page(slab))) { slab_err(s, slab, Not a slab page); return 0; }slab_page(slab)从struct slab取回对应的struct page较新内核里struct slab与struct page关系密切可能有转换。PageSlab()页标志确认该页确实是 SLUB 管理的 slab 页而不是普通匿名页、页缓存页等。失败则报告Not a slab page——说明传进来的slab根本不是 slab。3. 对象总数上限maxobj (PAGE_SIZE oo_order(s-oo)) / s-size; if (slab-objects maxobj) { slab_err(s, slab, objects %u max %u, slab-objects, maxobj); return 0; }maxobj一个 slab 页理论上最多能放的对象数由页大小除以对象槽位大小算出。如果slab-objects超过这个上限说明字段被破坏或缓存布局不一致。这是前面order_objects()的简化版不含元数据扣除用于上限判断足够。4. inuse 不超 objectsif (slab-inuse slab-objects) { slab_err(s, slab, inuse %u max %u, slab-inuse, slab-objects); return 0; }inuse已分配对象数不能超过objects总对象数。超过说明计数错误。5. objects 为 0 时 inuse 必须为 0if (slab-objects 0 slab-inuse ! 0) { slab_err(s, slab, inuse %u, but no objects, slab-inuse); return 0; }空 slabobjects 0不应有已分配对象。这是边界情况的一致性检查。三、校验层次check_slab()是第一层只检查 slab 页的结构字段是否合理check_slab(s, slab) ← 本函数页级基本状态 ├─ 地址有效 ├─ 是 slab 页 ├─ objects ≤ 上限 ├─ inuse ≤ objects └─ objects0 ⇒ inuse0 validate_slab(s, slab, map) ├─ check_slab(s, slab) ← 先做页级检查 ├─ __fill_map(...) ← 填充已分配位图 └─ for_each_object(...) └─ check_object(...) ← 对象级详细校验层次函数检查内容页级check_slab地址、页类型、objects/inuse 合理范围对象级check_object红区、poison、padding 内存内容汇总validate_slab组合前两者遍历所有对象四、与slab_err()的配合每个失败分支都调用slab_err()slab_err(s, slab, Not a slab page);回顾slab_err()__printf(3, 4)编译期格式检查。KUnit 环境下静默计数。__slab_bug()打印错误描述。__slab_err(slab)打印 slab 状态objects/inuse/freelist/flags。add_taint(TAINT_BAD_PAGE, ...)污染内核。所以check_slab发现异常时日志会自动附带 slab 状态方便定位。五、输出示例 BUG kmalloc-64 (debug): Not a slab page ... Not a slab page Slab 0xffffea0004a8c000 objects0 used1 fp0x0000000000000000 flags-或BUG kmalloc-64 (debug): inuse 65 max 64 Slab 0xffffea0004a8c000 objects

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑