Message ID | 20200813035509.739-1-jarod@redhat.com |
---|---|
State | Superseded |
Delegated to: | David Miller |
Headers | show |
Series | [net] bonding: show saner speed for broadcast mode | expand |
Jarod Wilson <jarod@redhat.com> wrote: >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 lowest active interface. Did you mean "slowest" here? >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 >Signed-off-by: Jarod Wilson <jarod@redhat.com> Did you notice this by inspection, or did it come up in use somewhere? I can't recall ever hearing of anyone using broadcast mode, so I'm curious if there is a use for it, but this change seems reasonable enough regardless. -J Acked-by: Jay Vosburgh <jay.vosburgh@canonical.com> >--- > drivers/net/bonding/bond_main.c | 21 ++++++++++++++++++--- > 1 file changed, 18 insertions(+), 3 deletions(-) > >diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c >index 5ad43aaf76e5..c853ca67058c 100644 >--- a/drivers/net/bonding/bond_main.c >+++ b/drivers/net/bonding/bond_main.c >@@ -4552,13 +4552,23 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) > 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_link_ksettings(struct net_device *bond_dev, > struct ethtool_link_ksettings *cmd) > { > struct bonding *bond = netdev_priv(bond_dev); >- unsigned long speed = 0; > struct list_head *iter; > struct slave *slave; >+ u32 speed = 0; > > cmd->base.duplex = DUPLEX_UNKNOWN; > cmd->base.port = PORT_OTHER; >@@ -4570,8 +4580,13 @@ static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev, > */ > 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 (cmd->base.duplex == DUPLEX_UNKNOWN && > slave->duplex != DUPLEX_UNKNOWN) > cmd->base.duplex = slave->duplex; >-- >2.20.1 >
On Thu, Aug 13, 2020 at 1:30 AM Jay Vosburgh <jay.vosburgh@canonical.com> wrote: > > Jarod Wilson <jarod@redhat.com> wrote: > > >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 lowest active interface. > > Did you mean "slowest" here? I think I was thinking "lowest speed", but the way it's written does seem a little ambiguous, and slowest would fit better. I'll repost with slowest. > >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 > >Signed-off-by: Jarod Wilson <jarod@redhat.com> > > Did you notice this by inspection, or did it come up in use > somewhere? I can't recall ever hearing of anyone using broadcast mode, > so I'm curious if there is a use for it, but this change seems > reasonable enough regardless. Someone working on our virt management tools was working on something displaying bonding speeds in the UI, and reached out, thinking the reporting for broadcast mode was wrong. My response was similar: I don't think I've ever actually used broadcast mode or heard of anyone using it, but for that one person who does, sure, we can probably make that adjustment. :)
On Wed, Aug 12, 2020 at 10:29:56PM -0700, Jay Vosburgh wrote: > Did you notice this by inspection, or did it come up in use > somewhere? I can't recall ever hearing of anyone using broadcast mode, > so I'm curious if there is a use for it, but this change seems > reasonable enough regardless. I did actually encountered our customers using broadcast mode twice. But I have to disappoint you, their "use for it" was rather an abuse. One of them had a number of hosts, each having two NICs in broadcast mode bond, one connected to one switch and one connected to another switch (with no direct connection between the switches). Having each packet duplicated when everything worked triggered some corner cases in networking stack (IIRC one issue in fragment reassembly and one in TCP lockless listener). Thankfully I was eventually able to convince them that this kind of redundancy does not really work if one host loses connection to one switch and another host to the other. I don't remember the other use case from the top of my head but I'm quite sure it made even less sense. Michal
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 5ad43aaf76e5..c853ca67058c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4552,13 +4552,23 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) 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_link_ksettings(struct net_device *bond_dev, struct ethtool_link_ksettings *cmd) { struct bonding *bond = netdev_priv(bond_dev); - unsigned long speed = 0; struct list_head *iter; struct slave *slave; + u32 speed = 0; cmd->base.duplex = DUPLEX_UNKNOWN; cmd->base.port = PORT_OTHER; @@ -4570,8 +4580,13 @@ static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev, */ 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 (cmd->base.duplex == DUPLEX_UNKNOWN && slave->duplex != DUPLEX_UNKNOWN) cmd->base.duplex = slave->duplex;
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 lowest 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 Signed-off-by: Jarod Wilson <jarod@redhat.com> --- drivers/net/bonding/bond_main.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)