| From foo@baz Wed Aug 26 04:19:14 PM CEST 2020 |
| From: Jarod Wilson <jarod@redhat.com> |
| Date: Thu, 13 Aug 2020 10:09:00 -0400 |
| Subject: bonding: show saner speed for broadcast mode |
| |
| From: Jarod Wilson <jarod@redhat.com> |
| |
| [ Upstream commit 4ca0d9ac3fd8f9f90b72a15d8da2aca3ffb58418 ] |
| |
| Broadcast mode bonds transmit a copy of all traffic simultaneously out of |
| all interfaces, so the "speed" of the bond isn't really the aggregate of |
| all interfaces, but rather, the speed of the slowest active interface. |
| |
| Also, the type of the speed field is u32, not unsigned long, so adjust |
| that accordingly, as required to make min() function here without |
| complaining about mismatching types. |
| |
| Fixes: bb5b052f751b ("bond: add support to read speed and duplex via ethtool") |
| CC: Jay Vosburgh <j.vosburgh@gmail.com> |
| CC: Veaceslav Falico <vfalico@gmail.com> |
| CC: Andy Gospodarek <andy@greyhouse.net> |
| CC: "David S. Miller" <davem@davemloft.net> |
| CC: netdev@vger.kernel.org |
| Acked-by: Jay Vosburgh <jay.vosburgh@canonical.com> |
| Signed-off-by: Jarod Wilson <jarod@redhat.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/bonding/bond_main.c | 21 ++++++++++++++++++--- |
| 1 file changed, 18 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/net/bonding/bond_main.c |
| +++ b/drivers/net/bonding/bond_main.c |
| @@ -4132,13 +4132,23 @@ static netdev_tx_t bond_start_xmit(struc |
| return ret; |
| } |
| |
| +static u32 bond_mode_bcast_speed(struct slave *slave, u32 speed) |
| +{ |
| + if (speed == 0 || speed == SPEED_UNKNOWN) |
| + speed = slave->speed; |
| + else |
| + speed = min(speed, slave->speed); |
| + |
| + return speed; |
| +} |
| + |
| static int bond_ethtool_get_settings(struct net_device *bond_dev, |
| struct ethtool_cmd *ecmd) |
| { |
| struct bonding *bond = netdev_priv(bond_dev); |
| - unsigned long speed = 0; |
| struct list_head *iter; |
| struct slave *slave; |
| + u32 speed = 0; |
| |
| ecmd->duplex = DUPLEX_UNKNOWN; |
| ecmd->port = PORT_OTHER; |
| @@ -4150,8 +4160,13 @@ static int bond_ethtool_get_settings(str |
| */ |
| bond_for_each_slave(bond, slave, iter) { |
| if (bond_slave_can_tx(slave)) { |
| - if (slave->speed != SPEED_UNKNOWN) |
| - speed += slave->speed; |
| + if (slave->speed != SPEED_UNKNOWN) { |
| + if (BOND_MODE(bond) == BOND_MODE_BROADCAST) |
| + speed = bond_mode_bcast_speed(slave, |
| + speed); |
| + else |
| + speed += slave->speed; |
| + } |
| if (ecmd->duplex == DUPLEX_UNKNOWN && |
| slave->duplex != DUPLEX_UNKNOWN) |
| ecmd->duplex = slave->duplex; |