oo_order()的对称配套函数从打包值里取回objects。实现static inline unsigned int oo_objects(struct kmem_cache_order_objects x) { return x.x OO_MASK; }x.x OO_MASKOO_MASK (1 16) - 1 0xFFFF取低 16 位。高 16 位的 order 被掩掉只留 objects。与oo_order()的对称static inline unsigned int oo_order(struct kmem_cache_order_objects x) { return x.x OO_SHIFT; // 高 16 位 → order } static inline unsigned int oo_objects(struct kmem_cache_order_objects x) { return x.x OO_MASK; // 低 16 位 → objects }函数位操作取哪部分结果oo_order(x) OO_SHIFT16高 16 位orderoo_objects(x) OO_MASK0xFFFF低 16 位objects两者是oo_make()的逆操作构成完整的编解码闭环oo_make(order, size) → (order 16) | objects │ ┌───────────────┴───────────────┐ ▼ ▼ oo_order(x) oo_objects(x) x 16 x 0xFFFF → order → objects使用场景oo_objects()在 SLUB 里用于获取一个 slab 页内的对象总数// 初始化新 slab 的 freelist unsigned int objects oo_objects(s-oo); for_each_object(p, s, addr, objects) { set_freepointer(s, p, next); } // 计算统计信息 unsigned int total oo_objects(s-oo) * nr_slabs; // sysfs 输出 objs_per_slab oo_objects(s-oo)典型出现位置allocate_slab()/new_slab()建 freelist 时确定循环次数。calculate_sizes()试算方案时比较对象数。kmem_cache_shrink()、统计输出算总数。validate_slab()调试时校验对象数是否与slab-objects一致。注意点1. 结果受MAX_OBJS_PER_PAGE限制#define MAX_OBJS_PER_PAGE 32767 /* since slab.objects is u15 */oo_objects()理论上能返回最大 6553516 位但真实对象数受slab.objects是u15约束上限 32767。calculate_order()在选方案时会保证不超过这个上限所以实际返回值总是合法的。2. 与order_objects()的区别order_objects(order, size)临时计算输入 order 和 size返回理论对象数。oo_objects(x)从已打包的 OO 值提取是缓存创建时定好的结果之后直接查表式使用不再重算。后者更快、更一致一旦calculate_order()选定了s-oo后续所有地方都从它取不会再出现“order 和 objects 不匹配”的问题。3. 为什么用而不是%或再x.x OO_MASK // 对 (x.x OO_SHIFT) OO_SHIFT // 也能得到同样结果但多一条指令 OO_MASK是最直接、最高效的取低位方式编译器也能识别为位域提取。总结oo_objects(x)用x.x OO_MASK从打包的kmem_cache_order_objects中取回低 16 位的objects与oo_order()取高 16 位 order对称是oo_make()的逆操作之一用于建 freelist、统计和 sysfs 输出等需要“一个 slab 能放多少对象”的场景。