2020-08-13 03:56:29

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net] bonding: show saner speed for broadcast mode

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 <[email protected]>
CC: Veaceslav Falico <[email protected]>
CC: Andy Gospodarek <[email protected]>
CC: "David S. Miller" <[email protected]>
CC: [email protected]
Signed-off-by: Jarod Wilson <[email protected]>
---
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


2020-08-13 05:31:12

by Jay Vosburgh

[permalink] [raw]
Subject: Re: [PATCH net] bonding: show saner speed for broadcast mode

Jarod Wilson <[email protected]> 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 <[email protected]>
>CC: Veaceslav Falico <[email protected]>
>CC: Andy Gospodarek <[email protected]>
>CC: "David S. Miller" <[email protected]>
>CC: [email protected]
>Signed-off-by: Jarod Wilson <[email protected]>

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 <[email protected]>


>---
> 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
>

2020-08-13 14:10:24

by Jarod Wilson

[permalink] [raw]
Subject: Re: [PATCH net] bonding: show saner speed for broadcast mode

On Thu, Aug 13, 2020 at 1:30 AM Jay Vosburgh <[email protected]> wrote:
>
> Jarod Wilson <[email protected]> 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 <[email protected]>
> >CC: Veaceslav Falico <[email protected]>
> >CC: Andy Gospodarek <[email protected]>
> >CC: "David S. Miller" <[email protected]>
> >CC: [email protected]
> >Signed-off-by: Jarod Wilson <[email protected]>
>
> 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. :)

--
Jarod Wilson
[email protected]

2020-08-13 14:12:37

by Jarod Wilson

[permalink] [raw]
Subject: [PATCH net v2] bonding: show saner speed for broadcast mode

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 <[email protected]>
CC: Veaceslav Falico <[email protected]>
CC: Andy Gospodarek <[email protected]>
CC: "David S. Miller" <[email protected]>
CC: [email protected]
Acked-by: Jay Vosburgh <[email protected]>
Signed-off-by: Jarod Wilson <[email protected]>
---
v2: fix description to clarify speed == that of slowest active interface

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

2020-08-13 21:39:22

by Michal Kubecek

[permalink] [raw]
Subject: Re: [PATCH net] bonding: show saner speed for broadcast mode

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

2020-08-15 22:03:26

by David Miller

[permalink] [raw]
Subject: Re: [PATCH net v2] bonding: show saner speed for broadcast mode

From: Jarod Wilson <[email protected]>
Date: Thu, 13 Aug 2020 10:09:00 -0400

> 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 <[email protected]>
> CC: Veaceslav Falico <[email protected]>
> CC: Andy Gospodarek <[email protected]>
> CC: "David S. Miller" <[email protected]>
> CC: [email protected]
> Acked-by: Jay Vosburgh <[email protected]>
> Signed-off-by: Jarod Wilson <[email protected]>
> ---
> v2: fix description to clarify speed == that of slowest active interface

Applied, thank you.