【Linux 网络子系统深度拆解】收包路径全解:从 NIC 中断到 socket 接收队列

💡 原文中文,约23300字,阅读约需56分钟。
📝

内容提要

本文详细解析了Linux内核中网络包的收包路径,包括从网卡接收数据到用户态的各个阶段。重点介绍了关键函数如net_rx_action、ip_rcv和tcp_v4_rcv的作用,以及NAPI和软中断的调度机制。分析了网络性能瓶颈并提出优化建议,如调整netdev_budget和GRO设置,以提高高流量场景下的处理效率。

🎯

关键要点

  • 网络包从网卡到用户态的收包路径分为八个阶段,包括硬中断、软中断调度、驱动轮询、GRO聚合、L2协议分发、IP层处理、传输层处理和Socket投递。
  • 网卡通过DMA将数据写入内核的ring buffer,并通过MSI-X中断通知CPU,支持多队列网卡以实现流量分散。
  • net_rx_action()是收包路径的调度中枢,控制每次处理的包数和时间预算,关键参数包括netdev_budget和netdev_budget_usecs。
  • 驱动的poll函数负责从ring buffer中读取数据并填充sk_buff,eth_type_trans()函数解析以太网帧头并设置协议类型。
  • GRO(Generic Receive Offload)在napi_gro_receive()中聚合多个小包以减少协议栈处理次数,提升性能。
  • netif_receive_skb()是L2到L3的分水岭,负责将skb交给相应的协议处理函数,如ip_rcv()和tcp_v4_rcv()。
  • tcp_v4_rcv()处理TCP包时需要考虑socket锁竞争,使用backlog队列来暂存被锁住的包,避免处理延迟。
  • TCP socket的接收队列分为sk_receive_queue和sk_backlog,前者用于直接入队,后者用于锁住时的暂存。
  • 通过bpftrace可以追踪收包路径的延迟、监控softirq的处理情况以及丢包原因,帮助优化网络性能。
  • 关键性能参数如NAPI weight、netdev_budget、gro_flush_timeout等可以通过调优来提升高流量场景下的处理效率。

延伸问答

Linux网络包的收包路径包括哪些阶段?

收包路径分为八个阶段:硬中断、软中断调度、驱动轮询、GRO聚合、L2协议分发、IP层处理、传输层处理和Socket投递。

net_rx_action函数的作用是什么?

net_rx_action是收包路径的调度中枢,控制每次处理的包数和时间预算。

GRO(Generic Receive Offload)在收包过程中有什么作用?

GRO用于聚合多个小包以减少协议栈处理次数,从而提升性能。

如何优化Linux网络性能?

可以通过调整netdev_budget和GRO设置等参数来优化网络性能,特别是在高流量场景下。

tcp_v4_rcv函数在处理TCP包时需要注意什么?

tcp_v4_rcv需要考虑socket锁竞争,使用backlog队列暂存被锁住的包以避免处理延迟。

如何使用bpftrace监控收包路径的性能?

可以使用bpftrace追踪收包路径的延迟、监控softirq处理情况以及丢包原因,帮助优化网络性能。

➡️

继续阅读