mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 00:39:48 +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
2 changed files with 30 additions and 26 deletions
|
@ -427,7 +427,7 @@ int ib_cache_gid_add(struct ib_device *ib_dev, u8 port,
|
||||||
static int
|
static int
|
||||||
_ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
|
_ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
|
||||||
union ib_gid *gid, struct ib_gid_attr *attr,
|
union ib_gid *gid, struct ib_gid_attr *attr,
|
||||||
bool default_gid)
|
unsigned long mask, bool default_gid)
|
||||||
{
|
{
|
||||||
struct ib_gid_table *table;
|
struct ib_gid_table *table;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -437,12 +437,7 @@ _ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
|
||||||
|
|
||||||
mutex_lock(&table->lock);
|
mutex_lock(&table->lock);
|
||||||
|
|
||||||
ix = find_gid(table, gid, attr, default_gid,
|
ix = find_gid(table, gid, attr, default_gid, mask, NULL);
|
||||||
GID_ATTR_FIND_MASK_GID |
|
|
||||||
GID_ATTR_FIND_MASK_GID_TYPE |
|
|
||||||
GID_ATTR_FIND_MASK_DEFAULT |
|
|
||||||
GID_ATTR_FIND_MASK_NETDEV,
|
|
||||||
NULL);
|
|
||||||
if (ix < 0) {
|
if (ix < 0) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
@ -462,7 +457,12 @@ _ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
|
||||||
int ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
|
int ib_cache_gid_del(struct ib_device *ib_dev, u8 port,
|
||||||
union ib_gid *gid, struct ib_gid_attr *attr)
|
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,
|
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,
|
unsigned long gid_type_mask,
|
||||||
enum ib_cache_gid_default_mode mode)
|
enum ib_cache_gid_default_mode mode)
|
||||||
{
|
{
|
||||||
union ib_gid gid;
|
union ib_gid gid = { };
|
||||||
struct ib_gid_attr gid_attr;
|
struct ib_gid_attr gid_attr;
|
||||||
struct ib_gid_table *table;
|
struct ib_gid_table *table;
|
||||||
unsigned int gid_type;
|
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;
|
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));
|
memset(&gid_attr, 0, sizeof(gid_attr));
|
||||||
gid_attr.ndev = ndev;
|
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;
|
gid_attr.gid_type = gid_type;
|
||||||
|
|
||||||
if (mode == IB_CACHE_GID_DEFAULT_MODE_SET) {
|
if (mode == IB_CACHE_GID_DEFAULT_MODE_SET) {
|
||||||
mask = GID_ATTR_FIND_MASK_GID_TYPE |
|
make_default_gid(ndev, &gid);
|
||||||
GID_ATTR_FIND_MASK_DEFAULT;
|
|
||||||
__ib_cache_gid_add(ib_dev, port, &gid,
|
__ib_cache_gid_add(ib_dev, port, &gid,
|
||||||
&gid_attr, mask, true);
|
&gid_attr, mask, true);
|
||||||
} else if (mode == IB_CACHE_GID_DEFAULT_MODE_DELETE) {
|
} 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 *rdma_ndev)
|
||||||
{
|
{
|
||||||
struct net_device *real_dev = rdma_vlan_dev_real_dev(event_ndev);
|
struct net_device *real_dev = rdma_vlan_dev_real_dev(event_ndev);
|
||||||
|
unsigned long gid_type_mask;
|
||||||
|
|
||||||
if (!rdma_ndev)
|
if (!rdma_ndev)
|
||||||
return;
|
return;
|
||||||
|
@ -264,10 +265,14 @@ static void bond_delete_netdev_default_gids(struct ib_device *ib_dev,
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
|
||||||
if (rdma_is_upper_dev_rcu(rdma_ndev, event_ndev) &&
|
if (((rdma_ndev != event_ndev &&
|
||||||
is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev) ==
|
!rdma_is_upper_dev_rcu(rdma_ndev, event_ndev)) ||
|
||||||
BONDING_SLAVE_STATE_INACTIVE) {
|
is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev)
|
||||||
unsigned long gid_type_mask;
|
==
|
||||||
|
BONDING_SLAVE_STATE_INACTIVE)) {
|
||||||
|
rcu_read_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
@ -276,9 +281,6 @@ static void bond_delete_netdev_default_gids(struct ib_device *ib_dev,
|
||||||
ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev,
|
ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev,
|
||||||
gid_type_mask,
|
gid_type_mask,
|
||||||
IB_CACHE_GID_DEFAULT_MODE_DELETE);
|
IB_CACHE_GID_DEFAULT_MODE_DELETE);
|
||||||
} else {
|
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enum_netdev_ipv4_ips(struct ib_device *ib_dev,
|
static void enum_netdev_ipv4_ips(struct ib_device *ib_dev,
|
||||||
|
|
Loading…
Reference in a new issue