mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
net/mlx5: Lag, record inactive state of bond device
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>
This commit is contained in:
parent
4f4551435c
commit
54493a08e2
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
|
|
@ -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++;
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user