性能·网络 / 命令文档
Linux内核网络栈研究
概述
从数据包接收到发送深入其中
学习目标
通过本课程,你将深入理解Linux内核如何处理网络数据包,掌握从硬件中断到用户空间的完整数据流程,并了解网络栈各层的核心机制。
7用户空间应用层
应用程序通过Socket API与内核通信
6Socket层
提供统一的网络编程接口,管理socket描述符
5传输层 (TCP/UDP)
处理端到端的可靠传输和不可靠传输
4网络层 (IP)
处理路由、分片、重组等网络层功能
3Netfilter框架
提供包过滤、NAT、连接跟踪等功能
2数据链路层
处理以太网帧、ARP协议等
1网络设备驱动层
与网卡硬件直接交互,处理中断和DMA
从网卡到应用程序的数据包旅程
网卡接收数据包
硬件中断
DMA传输
软中断(NET_RX)
协议栈处理
Socket缓冲
用户空间读取
关键概念:NAPI (New API) 现代Linux使用NAPI机制来优化网络性能,在高负载时切换到轮询模式,避免中断风暴。
// 简化的数据包接收流程
网卡:通过DMA方式,将网络包放到收包队列中,然后硬中断
网卡中断处理程序:
static int netif_rx(struct sk_buff *skb)
{
// 1. 获取当前CPU的接收队列
struct softnet_data *sd = this_cpu_ptr(&softnet_data);
// 2. 将数据包加入队列
enqueue_to_backlog(skb, get_cpu(), &qtail);
// 3. 触发软中断处理
__raise_softirq_irqoff(NET_RX_SOFTIRQ);
return NET_RX_SUCCESS;
}
// 软中断处理函数
static void net_rx_action(struct softirq_action *h)
{
// 处理接收队列中的所有数据包
process_backlog(&sd->process_queue, "a, jiffies + 2);
}
内核协议栈:从缓冲区取出网络帧
网络协议栈:从下到上处理网络帧
- 链路层:解析以太网帧,去掉帧头帧尾,交给网络层
- 网络层:对IP头进行处理,确认需要本机处理,去掉IP头,交给传输层
- 传输层:对TCP/UDP报文处理,根据(源IP,源端口,目标IP,目标端口)找出对应的socket,将数据包copy到对应Socket的接收缓存中
用户空间应用程序:通过Socket调用读取应用数据从应用程序到网卡的数据包旅程
应用程序发送
Socket层处理
协议栈封装
队列规程(Qdisc)
网卡驱动
DMA传输
物理发送
性能优化:TX队列管理 现代网卡支持多队列发送,可以并行处理多个数据流,显著提高发送性能。
sk_buff - 网络数据包的抽象
struct sk_buff {
struct sk_buff *next, *prev; // 链表指针
struct net_device *dev; // 关联的网络设备
unsigned int len; // 数据长度
unsigned int data_len; // 分片数据长度
__u16 protocol; // 协议类型
__u16 transport_header; // 传输层头偏移
__u16 network_header; // 网络层头偏移
__u16 mac_header; // MAC层头偏移
unsigned char *data; // 数据指针
unsigned char *tail; // 尾部指针
unsigned char *end; // 缓冲区结束
unsigned char *head; // 缓冲区开始
struct sock *sk; // 关联的socket
};sk_buff是Linux网络栈的核心数据结构,它抽象了网络数据包,支持零拷贝操作和高效的头部操作。
net_device - 网络设备抽象
struct net_device {
char name[IFNAMSIZ]; // 设备名称 (eth0, wlan0等)
struct net_device_ops *netdev_ops; // 设备操作函数集
unsigned int mtu; // 最大传输单元
unsigned char addr_len; // 硬件地址长度
unsigned char dev_addr[MAX_ADDR_LEN]; // MAC地址
struct netdev_queue *_tx; // 发送队列
unsigned int real_num_tx_queues; // 实际TX队列数
struct Qdisc *qdisc; // 队列规程
const struct net_device_stats *(*get_stats)(struct net_device *dev);
};socket - 套接字抽象
struct socket {
socket_state state; // socket状态
short type; // socket类型 (SOCK_STREAM/DGRAM)
unsigned long flags; // 标志位
struct file *file; // 关联的文件描述符
struct sock *sk; // 协议相关的sock结构
const struct proto_ops *ops; // 协议操作函数集
struct socket_wq __rcu *wq; // 等待队列
};网络性能优化技术
| 技术 | 作用 | 适用场景 | 性能提升 |
|---|---|---|---|
| NAPI | 中断与轮询混合模式 | 高负载网络环境 | 减少CPU中断开销 |
| 多队列网卡 | 并行处理多个数据流 | 多核CPU系统 | 提高并发处理能力 |
| CPU亲和性 | 绑定中断到特定CPU | 延迟敏感应用 | 减少缓存miss |
| 零拷贝 | 避免数据在内核和用户空间拷贝 | 大量数据传输 | 显著减少CPU使用 |
| TSO/GSO | 大包分段卸载 | 高带宽应用 | 减少协议栈开销 |
实战调试技巧
常用调试工具和命令
# 查看网络接口统计信息 cat /proc/net/dev # 查看socket连接状态 ss -tuln # 监控网络中断 watch -n 1 'cat /proc/interrupts | grep eth' # 查看网络队列状态 tc -s qdisc show dev eth0 # 使用perf分析网络性能 perf record -g -e cycles:k -- stress-network perf report
性能调优参数: • net.core.rmem_max: 增加接收缓冲区大小 • net.core.wmem_max: 增加发送缓冲区大小 • net.core.netdev_max_backlog: 调整网卡队列长度 • net.ipv4.tcp_rmem/tcp_wmem: TCP专用缓冲区设置
总结与要点
记住这些核心概念: 1. 网络栈是分层架构,每层都有特定的职责 2. sk_buff是数据包在内核中的统一表示 3. NAPI机制是现代网络性能优化的基础 4. 理解中断和软中断的处理机制 5. 零拷贝和卸载技术是性能优化的关键
深入学习建议:
1. 阅读内核源码,特别是net/core目录
2. 实际配置和调优网络参数
3. 使用工具分析网络性能瓶颈
4. 理解不同应用场景的优化策略