round_down是 Linux 内核中与round_up配对的宏用于将数值向下对齐到指定大小的整数倍。它同样定义在include/linux/math.h旧版本在kernel.h。定义与原理#define round_down(x, y) ({ \ typeof(x) _x (x); \ typeof(y) _y (y); \ (void)(_x _y); \ __round_down(_x, _y); \ })其核心计算逻辑是round_down(x, y) (x / y) * y当y是 2 的幂时编译器会优化为位运算round_down(x, y) x ~(y - 1)核心作用将x向下取整到y的整数倍。如果x已经是y的倍数则返回x本身。表达式结果说明round_down(5, 4)45 向下对齐到 4 的倍数得到 4round_down(8, 4)8已经是 4 的倍数不变round_down(9, 4)89 向下对齐到 4 的倍数得到 8round_down(0, 4)00 是任何数的倍数round_down(4095, 4096)04095 向下对齐到页边界得到 0round_down(4096, 4096)4096正好是一个页内核中的典型用途round_down最常见的场景是获取某个地址或偏移量所属的边界起始位置获取页内偏移的页起始地址page_addr round_down(addr, PAGE_SIZE); offset addr - page_addr; // 页内偏移计算包含某个地址的块或扇区起始位置block_start round_down(offset, block_size);文件系统块对齐将文件偏移量向下对齐到文件系统块大小。与round_up的关系宏行为示例round_up(x, y)向上对齐到 y 的倍数round_up(5, 4) 8round_down(x, y)向下对齐到 y 的倍数round_down(5, 4) 4两者共同构成了内核中对齐操作的基础。一个常见的组合用法是start round_down(addr, PAGE_SIZE); // 包含 addr 的页起始地址 end round_up(addr len, PAGE_SIZE); // 覆盖范围的页结束地址使用注意与round_up一样y必须是正整数通常为 2 的幂。宏内部的类型检查(void)(_x _y)确保两个参数类型兼容。对于有符号数round_down的行为依赖于整数除法的截断规则使用时需注意负数场景。
