Skip to content

Commit

Permalink
net/mlx5: Lag, record inactive state of bond device
Browse files Browse the repository at this point in the history
A bond device will drop duplicate packets (received on inactive ports)
by default. A flag (all_slaves_active) can be set to override such
behaviour. This flag is a global flag per bond device (ALB mode isn't
supported by mlx5 driver so it can be ignored)

When NETDEV_CHANGEUPPER / NETDEV_CHANGEINFODATA event is received check if
there is an interface that is inactive.

Downstream patch will use this information in order to decide if a drop
rule is needed.

Signed-off-by: Mark Bloch <mbloch@nvidia.com>
Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
  • Loading branch information
Mark Bloch authored and Saeed Mahameed committed Feb 23, 2022
1 parent 4f45514 commit 54493a0
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
49 changes: 47 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
*/

#include <linux/netdevice.h>
#include <net/bonding.h>
#include <linux/mlx5/driver.h>
#include <linux/mlx5/eswitch.h>
#include <linux/mlx5/vport.h>
Expand Down Expand Up @@ -619,6 +620,8 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
struct net_device *upper = info->upper_dev, *ndev_tmp;
struct netdev_lag_upper_info *lag_upper_info = NULL;
bool is_bonded, is_in_lag, mode_supported;
bool has_inactive = 0;
struct slave *slave;
int bond_status = 0;
int num_slaves = 0;
int changed = 0;
Expand All @@ -638,8 +641,12 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
rcu_read_lock();
for_each_netdev_in_bond_rcu(upper, ndev_tmp) {
idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev_tmp);
if (idx >= 0)
if (idx >= 0) {
slave = bond_slave_get_rcu(ndev_tmp);
if (slave)
has_inactive |= bond_is_slave_inactive(slave);
bond_status |= (1 << idx);
}

num_slaves++;
}
Expand All @@ -654,6 +661,7 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
tracker->hash_type = lag_upper_info->hash_type;
}

tracker->has_inactive = has_inactive;
/* Determine bonding status:
* A device is considered bonded if both its physical ports are slaves
* of the same lag master, and only them.
Expand Down Expand Up @@ -710,6 +718,38 @@ static int mlx5_handle_changelowerstate_event(struct mlx5_lag *ldev,
return 1;
}

static int mlx5_handle_changeinfodata_event(struct mlx5_lag *ldev,
struct lag_tracker *tracker,
struct net_device *ndev)
{
struct net_device *ndev_tmp;
struct slave *slave;
bool has_inactive = 0;
int idx;

if (!netif_is_lag_master(ndev))
return 0;

rcu_read_lock();
for_each_netdev_in_bond_rcu(ndev, ndev_tmp) {
idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev_tmp);
if (idx < 0)
continue;

slave = bond_slave_get_rcu(ndev_tmp);
if (slave)
has_inactive |= bond_is_slave_inactive(slave);
}
rcu_read_unlock();

if (tracker->has_inactive == has_inactive)
return 0;

tracker->has_inactive = has_inactive;

return 1;
}

static int mlx5_lag_netdev_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
Expand All @@ -718,7 +758,9 @@ static int mlx5_lag_netdev_event(struct notifier_block *this,
struct mlx5_lag *ldev;
int changed = 0;

if ((event != NETDEV_CHANGEUPPER) && (event != NETDEV_CHANGELOWERSTATE))
if (event != NETDEV_CHANGEUPPER &&
event != NETDEV_CHANGELOWERSTATE &&
event != NETDEV_CHANGEINFODATA)
return NOTIFY_DONE;

ldev = container_of(this, struct mlx5_lag, nb);
Expand All @@ -734,6 +776,9 @@ static int mlx5_lag_netdev_event(struct notifier_block *this,
changed = mlx5_handle_changelowerstate_event(ldev, &tracker,
ndev, ptr);
break;
case NETDEV_CHANGEINFODATA:
changed = mlx5_handle_changeinfodata_event(ldev, &tracker, ndev);
break;
}

ldev->tracker = tracker;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct lag_tracker {
enum netdev_lag_tx_type tx_type;
struct netdev_lag_lower_state_info netdev_state[MLX5_MAX_PORTS];
unsigned int is_bonded:1;
unsigned int has_inactive:1;
enum netdev_lag_hash hash_type;
};

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ bool mlx5_lag_is_multipath(struct mlx5_core_dev *dev)
static void mlx5_lag_set_port_affinity(struct mlx5_lag *ldev,
enum mlx5_lag_port_affinity port)
{
struct lag_tracker tracker;
struct lag_tracker tracker = {};

if (!__mlx5_lag_is_multipath(ldev))
return;
Expand Down

0 comments on commit 54493a0

Please sign in to comment.