diff options
author | Parav Pandit <parav@mellanox.com> | 2018-04-23 09:58:19 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2018-04-23 17:28:18 -0400 |
commit | dc5640f294e4ff6b89047cb4a0dfa931d5f0cd1f (patch) | |
tree | 7fd03f1654ba12b3ee8afa92dbc58796537d91ba /drivers/infiniband/core/cache.c | |
parent | 22c01ee4b8a8c000c490dfc479e175404e64167b (diff) |
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: 238fdf48f2b5 ("IB/core: Add RoCE table bonding support")
Fixes: 598ff6bae689 ("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>
Diffstat (limited to 'drivers/infiniband/core/cache.c')
-rw-r--r-- | drivers/infiniband/core/cache.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 8e6a4f05f3ea..fb2d347f760f 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c | |||
@@ -427,7 +427,7 @@ int ib_cache_gid_add(struct ib_device *ib_dev, u8 port, | |||
427 | static int | 427 | static int |
428 | _ib_cache_gid_del(struct ib_device *ib_dev, u8 port, | 428 | _ib_cache_gid_del(struct ib_device *ib_dev, u8 port, |
429 | union ib_gid *gid, struct ib_gid_attr *attr, | 429 | union ib_gid *gid, struct ib_gid_attr *attr, |
430 | bool default_gid) | 430 | unsigned long mask, bool default_gid) |
431 | { | 431 | { |
432 | struct ib_gid_table *table; | 432 | struct ib_gid_table *table; |
433 | int ret = 0; | 433 | int ret = 0; |
@@ -437,12 +437,7 @@ _ib_cache_gid_del(struct ib_device *ib_dev, u8 port, | |||
437 | 437 | ||
438 | mutex_lock(&table->lock); | 438 | mutex_lock(&table->lock); |
439 | 439 | ||
440 | ix = find_gid(table, gid, attr, default_gid, | 440 | ix = find_gid(table, gid, attr, default_gid, mask, NULL); |
441 | GID_ATTR_FIND_MASK_GID | | ||
442 | GID_ATTR_FIND_MASK_GID_TYPE | | ||
443 | GID_ATTR_FIND_MASK_DEFAULT | | ||
444 | GID_ATTR_FIND_MASK_NETDEV, | ||
445 | NULL); | ||
446 | if (ix < 0) { | 441 | if (ix < 0) { |
447 | ret = -EINVAL; | 442 | ret = -EINVAL; |
448 | goto out_unlock; | 443 | goto out_unlock; |
@@ -462,7 +457,12 @@ out_unlock: | |||
462 | int ib_cache_gid_del(struct ib_device *ib_dev, u8 port, | 457 | int ib_cache_gid_del(struct ib_device *ib_dev, u8 port, |
463 | union ib_gid *gid, struct ib_gid_attr *attr) | 458 | union ib_gid *gid, struct ib_gid_attr *attr) |
464 | { | 459 | { |
465 | return _ib_cache_gid_del(ib_dev, port, gid, attr, false); | 460 | unsigned long mask = GID_ATTR_FIND_MASK_GID | |
461 | GID_ATTR_FIND_MASK_GID_TYPE | | ||
462 | GID_ATTR_FIND_MASK_DEFAULT | | ||
463 | GID_ATTR_FIND_MASK_NETDEV; | ||
464 | |||
465 | return _ib_cache_gid_del(ib_dev, port, gid, attr, mask, false); | ||
466 | } | 466 | } |
467 | 467 | ||
468 | int ib_cache_gid_del_all_netdev_gids(struct ib_device *ib_dev, u8 port, | 468 | 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, | |||
741 | unsigned long gid_type_mask, | 741 | unsigned long gid_type_mask, |
742 | enum ib_cache_gid_default_mode mode) | 742 | enum ib_cache_gid_default_mode mode) |
743 | { | 743 | { |
744 | union ib_gid gid; | 744 | union ib_gid gid = { }; |
745 | struct ib_gid_attr gid_attr; | 745 | struct ib_gid_attr gid_attr; |
746 | struct ib_gid_table *table; | 746 | struct ib_gid_table *table; |
747 | unsigned int gid_type; | 747 | unsigned int gid_type; |
@@ -749,7 +749,9 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, | |||
749 | 749 | ||
750 | table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid; | 750 | table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid; |
751 | 751 | ||
752 | make_default_gid(ndev, &gid); | 752 | mask = GID_ATTR_FIND_MASK_GID_TYPE | |
753 | GID_ATTR_FIND_MASK_DEFAULT | | ||
754 | GID_ATTR_FIND_MASK_NETDEV; | ||
753 | memset(&gid_attr, 0, sizeof(gid_attr)); | 755 | memset(&gid_attr, 0, sizeof(gid_attr)); |
754 | gid_attr.ndev = ndev; | 756 | gid_attr.ndev = ndev; |
755 | 757 | ||
@@ -760,12 +762,12 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, | |||
760 | gid_attr.gid_type = gid_type; | 762 | gid_attr.gid_type = gid_type; |
761 | 763 | ||
762 | if (mode == IB_CACHE_GID_DEFAULT_MODE_SET) { | 764 | if (mode == IB_CACHE_GID_DEFAULT_MODE_SET) { |
763 | mask = GID_ATTR_FIND_MASK_GID_TYPE | | 765 | make_default_gid(ndev, &gid); |
764 | GID_ATTR_FIND_MASK_DEFAULT; | ||
765 | __ib_cache_gid_add(ib_dev, port, &gid, | 766 | __ib_cache_gid_add(ib_dev, port, &gid, |
766 | &gid_attr, mask, true); | 767 | &gid_attr, mask, true); |
767 | } else if (mode == IB_CACHE_GID_DEFAULT_MODE_DELETE) { | 768 | } else if (mode == IB_CACHE_GID_DEFAULT_MODE_DELETE) { |
768 | _ib_cache_gid_del(ib_dev, port, &gid, &gid_attr, true); | 769 | _ib_cache_gid_del(ib_dev, port, &gid, |
770 | &gid_attr, mask, true); | ||
769 | } | 771 | } |
770 | } | 772 | } |
771 | } | 773 | } |