1. Intel X710网卡,VF口统计不准
问题
- sar -n DEV 1 每两秒更新一次收包数量
- ethtool -S ethx 实时更新
原因:
- sar/ifconfig 数据来自 /proc/net/dev
- /proc/net/dev数据来自驱动内部统计
- iavf驱动每2秒执行一次watchdog_task,其中会将VF收包统计更新到netdev->stats
内核iavf驱动主要逻辑
1 2
| queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ * 2); iavf_request_stats(adapter);
|
Intel原厂工程师:
- get stats是一个低优先级任务 无必要去实时更新
- 2s只是开发这个驱动的工程师的一个经验值
- 在我看来1s周期也问题不大, 但永远也解不了你的问题 因为改为1s 你 0.5s统计也依然gap,改为100ms 你用50ms去查询也一样有gap,你明白我表达的意思
- 不是改小周期就好,需要考虑到get statistic是要访问到nic的hw registers ,属于i/o操作 过于频繁快速 会影响网卡性能
- 因为收发都要频繁访问硬件
- i/o操作是排它的 下一个访问要等上一次访问完成。 包括还需要走的pcie资源也一样
2. raw socket发包失败
问题
PF_PACKET RAW_SOCK,在网口down/up操作时,网口重新up口,第一个包会发送失败
原因:
- ifconfig ethX down时,会设置sk->sk_err为NETDOWN
- ifconfig ethX up后,第一次进入packet_snd函数 sock_alloc_send_pskb会检查sock_error
- 此时第一次分配skb直接返回错误,因此会失败
解决方案有2个:
- 只有第一个包会发送失败,因此发包失败时需要重试
- 网口down/up时重建socket,此时不会发送失败
3. raw socket收到杂包
原始流程:
1 2 3 4 5 6 7
| 1. syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(Htons(syscall.ETH_P_ALL))) 2. syscall.Bind 3. SO_ATTACH_FILTER 4. go recvPacket()
现象: 1. 每次启动时都会收到几个杂包
|
原因:
- 设置bpf过滤器生效之前,会有少量包进入socket缓冲区
- 一般情况下,业务逻辑会自己过滤收到的数据包,收到杂包也没问题
- 此时想直接在内核中过滤,不在业务中过滤(不好的行为)
- 需要收好几个协议的数据包,创建socket不可指定单一协议
处理,有以下方案:
- 业务中增加过滤操作
- 设置过滤规则后,清空缓冲区,启动收包协程
- 调整socket创建和设置流程, 如下:
1 2 3 4 5 6 7 8 9 10
| 1. syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, 0) 2. SO_ATTACH_FILTER 3. syscall.Bind( 4. go recvPacket()
说明: 1. socket指定协议0,raw socket在创建时不加入pt_type列表,也即不会收包 2. 先设置bpf规则,使之在收包之前生效 3. 执行bind操作,绑定网口,此时会加入pt_type列表,也即开始收包 4. 启动收包协程,此时收包即无杂包了
|