内核线程负责在Linux内核中发送网络数据包

时间:2013-12-15 03:08:01

标签: linux linux-kernel operating-system kernel

我正在阅读Linux内核的源代码,试图弄清楚Linux内核如何发送网络数据包,经过几个小时,我只能看到网络数据包流经TCP层,IP层,最后是数据链路层,我无法找出哪些线程在做这些工作。

我的问题是哪些内核线程负责发送网络数据包,它们在哪里? (因为我们可以将套接字设置为非阻塞并让用户应用程序尽可能快地发送网络数据包,所以当网络繁忙时,必须有一些队列来缓冲这些数据包,并且必须有一些内核线程在某个地方运行发送这些数据包。)

2 个答案:

答案 0 :(得分:2)

默认情况下,内核不使用线程发送网络数据包。

良好的网络芯片管理硬件中的数据包队列。 更便宜的芯片具有固定长度的队列或根本没有队列,并且在发送分组时引发中断;然后,内核将中断处理程序从其自己的队列中排队或提交下一个数据包。

此问题的softirq称为NET_TX_SOFTIRQ(请参阅net/core/dev.c)。 如果内核负载过重或配置为将工作移出中断,ksoftirq/*线程将处理softirqs。

答案 1 :(得分:0)

recv 程序:

  1. 网络芯片从电线接收数据

  2. 网络芯片通过DMA将数据放入内核的RingBuffer内存

  3. 网络芯片向cpu发送硬件IRQ

  4. cpu 处理 IRQ 的上半部分,非常快,然后生成一个软 IRQ 给 ksoftirqd

  5. 内核线程ksoftirqd关闭硬件IRQ,然后处理软IRQ的下半部分

    5.1 ksoftirqd线程执行网络驱动的igb_poll()函数,它从RingBuffer中获取数据,然后通过tcp/ip栈传输。即ip_rcv() -> tcp_rcv()...,最后将数据放入socket缓冲区。

    5.2 ksoftirqd 的工作完成

  6. 用户线程从其套接字缓冲区中获取数据。

发送过程:

大部分工作由内核态的用户线程处理。 如果重新安排用户线程,则 ksoftirqd 线程会执行剩余的工作。