使用内核模块覆盖非NAPI网络轮询处理程序

时间:2010-09-27 19:59:56

标签: c network-programming module linux-kernel

熟悉网络设备驱动程序的人都知道,内核和驱动程序之间的接口已更改为使用NAPI(新API)。在此范例中,轮询函数与napi_struct相关联,napi_struct是必须由设备驱动程序分配的新结构。无论如何,我有一个旧驱动程序,没有时间/意愿将其转换为NAPI。由于内核已经过修改以考虑NAPI,因此它们使用默认函数“process_backlog”(/net/core/dev.c)来处理pre-NAPI功能。此函数仍在每个数据包的中断上下文中调用(与轮询队列的NAPI相反,因此每次都不需要中断)。我需要覆盖此函数,但我的问题是,与设备驱动程序分配和创建的NAPI轮询函数不同,process_backlog在启动时与每个CPU的输入队列相关联。当我加载模块时,我可以使用

覆盖该方法
   struct softnet_data *queue, backup;
   queue = &__get_cpu_var(softnet_data);
   backup = *queue;
   queue->backlog.poll = my_process_backlog; 

这里的问题是这只会覆盖模块中CPU的队列。有没有什么方法可以在模块上下文中遍历所有CPU?我觉得必须有一些方法可以做到这一点。

干杯

1 个答案:

答案 0 :(得分:1)

这是一个真的坏主意。

但是,如果你想为每个cpu变量设置一些其他,你可以使用per_cpu(name, cpu)

更新:为什么这是一个坏主意?

因为您在加载驱动程序时对核心网络代码的一部分进行二进制修补。这会影响系统中的每个网络驱动程序,而不仅仅是您的。这就像拥有一个替换调度程序的内核模块。如果内核的其余部分是这样编写的,它将无法工作。

哦,你还记得在你的模块被移除后改回原来的process_backlog()吗?

如果您确实认为需要更改process_backlog(),那么您应该对源代码进行更改并分发自定义内核。或者向上游网络社区解释您需要的变化,并将其接受上游接受。

或者最好还是将你的驱动程序转换为NAPI,这并不难。