【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处理情况以及丢包原因,帮助优化网络性能。
➡️