Linux kernel netdev 为何限制 module_param,运行时参数如何配置?
结论
module_param() 仍是 Linux kernel 支持的模块参数接口。这条报错反映了 netdev 对新增用法的检查限制,不能据此认定该接口已在整个内核中被弃用。内核文档仍说明了模块参数的加载方式和运行时访问路径;netdev 的补丁讨论则明确反对继续新增模块参数。内核参数文档、netdev 补丁讨论
对于准备提交上游的 TCP 拥塞控制模块,没有可以直接替换 module_param() 的通用宏。应先确定参数的作用范围,再评估按 network namespace 保存的 sysctl 配置或已有网络配置接口。确有必要时,也可以考虑设计新的配置接口。
这条检查结果表示什么?
netdev/deprecated_api - fail - Found: 'module_param' was: 0 now: 11
检查器统计到的 module_param 匹配数量从 0 增加到 11,因此报告失败。这些数字既不是内核版本号,也不是运行时错误码。具体统计范围需要查看该次检查的日志和脚本,不能只凭摘要认定它扫描了整个内核。
NIPA 是 netdev 使用的补丁自动检查基础设施,其文档称 deprecated_api 用于检查补丁是否增加了受限制 API 的使用。检查项名称中的 deprecated 不足以证明某个接口在所有内核子系统中都已废弃。NIPA 检查说明
为什么模块参数不适合所有网络配置?
常见的模块参数直接对应模块中的静态变量。例如:
#include <linux/moduleparam.h>
static unsigned int tuning = 100;
module_param(tuning, uint, 0644);
MODULE_PARM_DESC(tuning, "Experimental tuning value");
这个片段用于说明机制,tuning 和数值 100 都是示例,不代表原问题中的实际参数。0644 允许具备相应权限的用户通过 sysfs 写入该参数;0444 表示只读,0 则不创建对应的 sysfs 参数入口。moduleparam.h 定义与注释
这里的静态变量由所有使用该模块的连接共享,不会自动为每个 network namespace 或 TCP socket 创建独立副本。如果不同容器、网络命名空间或连接需要不同配置,这种作用域就不合适。
将宏改为 module_param_named() 或 module_param_cb(),仍然使用的是模块参数机制,无法解决配置作用域问题,也不能视为已经满足 netdev 的审查要求。
运行时参数可以怎样配置?
网络命名空间内的默认值:评估 sysctl
如果参数表达的是某个 network namespace 中的 TCP 默认策略,可以评估实现按 namespace 保存的 sysctl。Linux 已有大量 TCP 配置采用这种方式,内核的 netns_ipv4 数据结构中也包含相应配置状态。TCP sysctl 文档、netns_ipv4 配置结构
迁移时,需要同时处理配置存储、namespace 的初始化和清理、参数范围校验,以及数据路径上的并发读取。把同一个全局变量挂到多个 namespace 的配置入口下,无法实现隔离。新增 sysctl 是否合理,也需要维护者审查。
需要结构化管理:评估已有接口或 Generic Netlink
如果配置包含多个属性,或需要查询和通知,可以评估 Netlink。Generic Netlink 提供动态注册的 family 和基于属性的消息格式,适合构建结构化控制接口。Generic Netlink 文档
应先检查是否已有适合的接口。新增 Generic Netlink family 需要设计用户态协议、权限检查和对象作用域。TCP 拥塞控制模块并没有因此获得一个可以直接接收任意算法参数的通用 Netlink 接口。
单个连接的设置:区分算法选择与算法调参
TCP_CONGESTION 可以为 socket 选择拥塞控制算法,net.ipv4.tcp_congestion_control 可以设置新连接默认使用的算法。它们都不能通用地调整任意算法的内部参数。TCP 拥塞控制配置说明
可以先查看当前系统已有的配置:
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control
这些命令用于查询算法及默认选择,不能替代原先的自定义参数。如果确实需要为每个连接分别调参,应评估现有 socket 接口是否覆盖需求;新增接口通常还涉及 TCP 核心代码和用户态 ABI 的设计。
这份补丁接下来应该怎么改?
先逐项说明这 11 处匹配涉及的参数:各自有什么用途,为什么必须暴露给用户,会影响哪些连接,以及修改后何时生效。实验阶段使用的调试开关,也应重新判断是否值得成为长期维护的用户接口。
然后根据实际作用域提出配置方案,在 netdev 的补丁讨论中说明选择依据。现有材料没有给出参数定义、目标内核版本或补丁代码,因此无法确定具体采用哪种接口,也无法给出可直接应用的迁移补丁。
如果只是本地实验,仍可用上面的 module_param() 方式暴露参数,但需要自行实现取值校验和并发访问保护。写入 sysfs 并不自动保证算法内部状态能安全切换到新配置;无论采用哪种控制接口,都需要处理这个问题。模块参数并发访问说明
备注:内容仅供参考。
