什么是bond
Linux 下的 bond 机制是一种网络接口绑定技术,它可将多个网络接口整合为一个逻辑接口,以实现负载均衡和冗余功能,从而提高网络连接的带宽和可靠性。
什么是bond4模式
Bond4 模式,也称为 802.3ad 模式,是 Linux 网络 bonding 的一种模式。它遵循 IEEE 802.3ad 标准,通过链路聚合控制协议(LACP)来实现链路聚合。在这种模式下,多个网络接口可以被聚合为一个逻辑接口,所有接口都处于活跃状态,能够动态地进行链路聚合或解聚,以适应网络流量的变化。Bond4 模式可以提供高带宽和冗余,适用于需要大带宽和高可靠性的网络环境。
诡异的现场
正常状态下,bond运行很正常,两个网口都有流量在运行。此时,对bond下的物理网口做了配置的修改(ethtool -G[ring buffer]/-A[auto negotiate]/-L[combined]),概率性出现一个网口流量跌0且持续性无流量的情况。
分析过程
- 驱动现场分析
对 bonding 代码予以修改,增添输出信息。构建问题状态之后,对输出信息加以观察。
(1)enp65s0f1 与 enp129s0f0 归属于同一个 bond
(2)就驱动输出来看,两个网口仅仅是 count 累计至 1,尚未达到 2 。count 为 1 ,致使后续进行 hash 时,针对 1 取余,仅通过一个网口 。
- 代码分析
(1)bond_3ad_xor_xmit 乃是用于选择网口进行发送的函数。slaves = rcu_dereference(bond->slave_arr);count = slaves 存在时?READ_ONCE(slaves->count) : 0;slave = slaves->arr[bond_xmit_hash(bond, skb) % count];
(2)在 bond_update_slave_arr 中,针对 count 存在修改之举。new_arr->arr[new_arr->count++] = slave;old_arr->count–;
(3)调用 bond_update_slave_arr 的位置,调用者应当仅仅持有 RTNL 锁,而不可持有其他锁。
1)bond_enslave:bond 添加 slave2)bond_release 》__bond_release_one:bond 释放 slave3)bond_mii_monitor(delay work)》bond_miimon_commit》bond_miimon_link_change:网口 mii 产生变化4)bond_arp_monitor(delay work)》bond_loadbalance_arp_mon:网口 arp 发生变化5)bond_netdev_event(notifier_block)》bond_slave_netdev_event(NETDEV_UP/CHANGE/DOWN):网口状态出现变化,NETDEV_UP = 1,NETDEV_DOWN = 2,NETDEV_CHANGE = 46)bond_open:Bond 被开启7)bond_slave_arr_handler(delay work):Slave 数组刷新工作队列。
(4)测试卸载加载驱动以及网卡配置调整,所涉及的调用流程如下:
1)hygon_tune.sh 流程:先是卸载加载网卡驱动,接着调整硬盘参数,再对网口参数进行调整。bond_netdev_event -》bond_release -》bond_enslave -》bond_netdev_event(down) -》bond_slave_arr_handler -》bond_netdev_event(change) -》bond_slave_arr_handler -》bond_netdev_event(change) -》bond_slave_arr
(5)网卡命令
ethtool –G –》 bond_netdev_event NETDEV_CHANGE
ethtool –A –》 bond_netdev_event,bond_slave_arr_handler NETDEV_CHANGE
ethtool –L –》 bond_netdev_event NETDEV_CHANGE
(6)加载驱动到bond状态正常所需时间记录
驱动 | 时间范围 | active变非active又变active时间范围 |
---|---|---|
E810(ice) | 4.3873~4.47秒 | 0.1 s |
云芯(sssnic) | 5.7481~5.85秒 | 0.25s |
(7)驱动异常原因
在加载驱动之际,bond 状态于特定时间范围之内(详见 (6) 时间),会存在波动(时而处于 active 状态,时而处于 backup 状态)。此时,当历经 bond_slave_can_tx 时,会由于 bond 状态有误,进而触发 continue ,网口便被忽视了。
结论及修复方案
- 加载驱动时,NetworkManager 自动识别网口的过程中,在一定时段内,bond 状态会产生波动,会从 active 降至非 active 再回归 active,此波动持续时间为 0.1 至 0.25 秒。倘若恰好在加载网口(通过 ethtool 修改网口配置)至 bond 时处于这段时间内,便会致使网口被忽略。进而使得仅有一个网口加入 tx 的队列中(即前一个加入的网口被覆盖)。
- E810 难以复现,缘由在于其异常时间极为短促,仅为 0.1 秒,极难捕捉到,但实际上确实存在问题。
- 修复可见 5.10 内核,bonding: Add array of all slaves 提交“Keep all slaves in array so it could be used to get the xmit slave assume all the slaves are active. The logic to add slave to the array is like the usable slaves, except that we also add slaves that currently can’t transmit - not up or active.”
gitee.com/anolis/clou…