mirror of
https://github.com/torvalds/linux.git
synced 2024-12-25 12:21:37 +00:00
IB/core: Fix deleting default GIDs when changing mac adddress
Before [1], When MAC address of the netdevice is changed, default GID is supposed to get deleted and added back which affects the node and/or port GUID in below sequence. netdevice_event() -> NETDEV_CHANGEADDR default_del_cmd() del_netdev_default_ips() bond_delete_netdev_default_gids() ib_cache_gid_set_default_gid() ib_cache_gid_del() add_cmd() [..] However, ib_cache_gid_del() was not getting invoked in non bonding scenarios because event_ndev and rdma_ndev are same. Therefore, fix such condition to ignore checking upper device when event ndev and rdma_dev are same; similar to bond_set_netdev_default_gids(). Which this fix ib_cache_gid_del() is invoked correctly; however ib_cache_gid_del() doesn't find the default GID for deletion because find_gid() was given default_gid = false with GID_ATTR_FIND_MASK_DEFAULT set. But it was getting overwritten by ib_cache_gid_set_default_gid() later on as part of add_cmd(). Therefore, mac address change used to work for default GID. With refactor series [1], this incorrect behavior is detected. Therefore, when deleting default GID, set default_gid and set MASK flag. when deleting IP based GID, clear default_gid and set MASK flag. [1] https://patchwork.kernel.org/patch/10319151/ Fixes:238fdf48f2
("IB/core: Add RoCE table bonding support") Fixes:598ff6bae6
("IB/core: Refactor GID modify code for RoCE") Signed-off-by: Parav Pandit <parav@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
parent
22c01ee4b8
commit
dc5640f294
@ -427,7 +427,7 @@ int ib_cache_gid_add(struct ib_device *ib_dev, u8 port,
|
||||
static int
|
||||
_ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
|
||||
union ib_gid *gid, struct ib_gid_attr *attr,
|
||||
bool default_gid)
|
||||
unsigned long mask, bool default_gid)
|
||||
{
|
||||
struct ib_gid_table *table;
|
||||
int ret = 0;
|
||||
@ -437,12 +437,7 @@ _ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
|
||||
|
||||
mutex_lock(&table->lock);
|
||||
|
||||
ix = find_gid(table, gid, attr, default_gid,
|
||||
GID_ATTR_FIND_MASK_GID |
|
||||
GID_ATTR_FIND_MASK_GID_TYPE |
|
||||
GID_ATTR_FIND_MASK_DEFAULT |
|
||||
GID_ATTR_FIND_MASK_NETDEV,
|
||||
NULL);
|
||||
ix = find_gid(table, gid, attr, default_gid, mask, NULL);
|
||||
if (ix < 0) {
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
@ -462,7 +457,12 @@ out_unlock:
|
||||
int ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
|
||||
union ib_gid *gid, struct ib_gid_attr *attr)
|
||||
{
|
||||
return _ib_cache_gid_del(ib_dev, port, gid, attr, false);
|
||||
unsigned long mask = GID_ATTR_FIND_MASK_GID |
|
||||
GID_ATTR_FIND_MASK_GID_TYPE |
|
||||
GID_ATTR_FIND_MASK_DEFAULT |
|
||||
GID_ATTR_FIND_MASK_NETDEV;
|
||||
|
||||
return _ib_cache_gid_del(ib_dev, port, gid, attr, mask, false);
|
||||
}
|
||||
|
||||
int ib_cache_gid_del_all_netdev_gids(struct ib_device *ib_dev, u8 port,
|
||||
@ -741,7 +741,7 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
|
||||
unsigned long gid_type_mask,
|
||||
enum ib_cache_gid_default_mode mode)
|
||||
{
|
||||
union ib_gid gid;
|
||||
union ib_gid gid = { };
|
||||
struct ib_gid_attr gid_attr;
|
||||
struct ib_gid_table *table;
|
||||
unsigned int gid_type;
|
||||
@ -749,7 +749,9 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
|
||||
|
||||
table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid;
|
||||
|
||||
make_default_gid(ndev, &gid);
|
||||
mask = GID_ATTR_FIND_MASK_GID_TYPE |
|
||||
GID_ATTR_FIND_MASK_DEFAULT |
|
||||
GID_ATTR_FIND_MASK_NETDEV;
|
||||
memset(&gid_attr, 0, sizeof(gid_attr));
|
||||
gid_attr.ndev = ndev;
|
||||
|
||||
@ -760,12 +762,12 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
|
||||
gid_attr.gid_type = gid_type;
|
||||
|
||||
if (mode == IB_CACHE_GID_DEFAULT_MODE_SET) {
|
||||
mask = GID_ATTR_FIND_MASK_GID_TYPE |
|
||||
GID_ATTR_FIND_MASK_DEFAULT;
|
||||
make_default_gid(ndev, &gid);
|
||||
__ib_cache_gid_add(ib_dev, port, &gid,
|
||||
&gid_attr, mask, true);
|
||||
} else if (mode == IB_CACHE_GID_DEFAULT_MODE_DELETE) {
|
||||
_ib_cache_gid_del(ib_dev, port, &gid, &gid_attr, true);
|
||||
_ib_cache_gid_del(ib_dev, port, &gid,
|
||||
&gid_attr, mask, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -255,6 +255,7 @@ static void bond_delete_netdev_default_gids(struct ib_device *ib_dev,
|
||||
struct net_device *rdma_ndev)
|
||||
{
|
||||
struct net_device *real_dev = rdma_vlan_dev_real_dev(event_ndev);
|
||||
unsigned long gid_type_mask;
|
||||
|
||||
if (!rdma_ndev)
|
||||
return;
|
||||
@ -264,21 +265,22 @@ static void bond_delete_netdev_default_gids(struct ib_device *ib_dev,
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (rdma_is_upper_dev_rcu(rdma_ndev, event_ndev) &&
|
||||
is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev) ==
|
||||
BONDING_SLAVE_STATE_INACTIVE) {
|
||||
unsigned long gid_type_mask;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
|
||||
|
||||
ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev,
|
||||
gid_type_mask,
|
||||
IB_CACHE_GID_DEFAULT_MODE_DELETE);
|
||||
} else {
|
||||
if (((rdma_ndev != event_ndev &&
|
||||
!rdma_is_upper_dev_rcu(rdma_ndev, event_ndev)) ||
|
||||
is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev)
|
||||
==
|
||||
BONDING_SLAVE_STATE_INACTIVE)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
|
||||
|
||||
ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev,
|
||||
gid_type_mask,
|
||||
IB_CACHE_GID_DEFAULT_MODE_DELETE);
|
||||
}
|
||||
|
||||
static void enum_netdev_ipv4_ips(struct ib_device *ib_dev,
|
||||
|
Loading…
Reference in New Issue
Block a user