前面的文章里面已经提到,Linux网络栈很复杂,而且没有一个完整监控优化的方案。如果你真的要进行网络栈的调优,需要花费大量的时间和精力来理解清楚网络系统是如何交互的。
在这个博客里有很多例子都可以证明这一点,建议你去做下这些配置。但在做参数调优之前,需要围绕着监控开发一套前后对比参数,用来证明调优的意义
调整正在连接其他物理机的网络配置是比较危险,你自己很容易陷入断网,所以不要在生产机器上进行调整,先在新机器上,等可以的话在到生产的机器
综述
这篇文章主要讲述Intel I350控制器,并且使用igb设备驱动。
首先看下从用户程序到网络设备网络数据的路径如下:
- 通过系统调用(sendto, sendmsg等)写数据
- 数据通过socket子系统到socket的协议族(AF_INET)
- 协议族会将数据传递到协议层中,这时候会组成数据包(packets)
- 数据会经过路由层,针对首次发送会填充目的和邻居到cache,如果网络地址需要查找则发送ARP请求
- 经过协议层,数据包会到达设备层
- 发送队列会通过XPS或者hash函数进行选择
- 调用驱动发送函数
- 数据会经过发送设备所对应的队列规则(qdisc)
- 队列规则(qdisc)可能会直接发送数据,也或者会将数据入队,等待NET_TX去软中断发送
10.最终数据会从qdisc到达驱动
11.驱动会创建DMA映射,从而使得设备可以从RAM中读取到数据
12.驱动发信号给设备,告诉数据已经准备就绪
13.设备从RAM中获取到数据然后发送
14.一旦发送完成,设备会触发中断表示已经发送完成
15.驱动会注册发送完成的中断服务程序,对于大部分的设备来说,这个服务程序只是简单的触发NAPI执行poll循环,并通过NET_RX软中断运行
16.poll循环函数中会调用驱动释放DMA映射与数据包