【问题标题】:What Kernel Threads are Responsible For Sending Network Packets in the Linux KernelLinux内核中哪些内核线程负责发送网络数据包
【发布时间】:2014-01-02 15:42:51
【问题描述】:

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

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

【问题讨论】:

标签: linux linux-kernel operating-system kernel


【解决方案1】:

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 线程会完成剩余的工作。

【讨论】:

    【解决方案2】:

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

    良好的网络芯片在硬件中管理数据包队列。 更便宜的芯片有一个固定长度的队列或根本没有队列,当一个数据包被传输时会引发一个中断;然后内核将来自中断处理程序的自己队列中的下一个数据包排入队列或提交。

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

    【讨论】:

    • 假设此时某个套接字的发送缓冲区已满,拥有该套接字的用户进程挂起。几分钟后,当网络空闲时,谁将数据包从套接字发送缓冲区中取出并重新发送?是不是有内核线程将这些数据包移动到芯片中的数据包队列中?如果没有,TCP 层如何知道何时重新发送此套接字的数据包?
    • 网络芯片在“网络空闲时”(即其他数据包已被处理时)引发中断。
    猜你喜欢
    • 2021-06-25
    • 2018-02-28
    • 2012-05-17
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多