Commit 408f1242 authored by Parav Pandit's avatar Parav Pandit Committed by Jason Gunthorpe

IB/core: Delete lower netdevice default GID entries in bonding scenario

When NETDEV_CHANGEUPPER event occurs, lower device is not yet established
as slave of the master, and when upper device is bond device, default GID
entries not deleted.

Due to this, when bond device is fully configured, default GID entries of
bond device cannot be added as default GID entries are occupied by the
lower netdevice. This is incorrect.

Default GID entries should really be of bond netdevice because in all RoCE
GIDs (default or IP), MAC address of the bond device will be used.  It is
confusing to have default GID of netdevice which is not really used for
any purpose.

Therefore, as first step, implement
(a) filter function which filters if a CHANGEUPPER event netdevice and
    associated upper device is master device or not.
(b) callback function which deletes the default GIDs of lower (event
    netdevice).
Signed-off-by: default avatarParav Pandit <parav@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent b9f09866
...@@ -208,6 +208,34 @@ static int upper_device_filter(struct ib_device *ib_dev, u8 port, ...@@ -208,6 +208,34 @@ static int upper_device_filter(struct ib_device *ib_dev, u8 port,
return res; return res;
} }
/**
* is_upper_ndev_bond_master_filter - Check if a given netdevice
* is bond master device of netdevice of the the RDMA device of port.
* @ib_dev: IB device to check
* @port: Port to consider for adding default GID
* @rdma_ndev: Pointer to rdma netdevice
* @cookie: Netdevice to consider to form a default GID
*
* is_upper_ndev_bond_master_filter() returns true if a cookie_netdev
* is bond master device and rdma_ndev is its lower netdevice. It might
* not have been established as slave device yet.
*/
static int
is_upper_ndev_bond_master_filter(struct ib_device *ib_dev, u8 port,
struct net_device *rdma_ndev,
void *cookie)
{
struct net_device *cookie_ndev = cookie;
bool match = false;
rcu_read_lock();
if (netif_is_bond_master(cookie_ndev) &&
rdma_is_upper_dev_rcu(rdma_ndev, cookie_ndev))
match = true;
rcu_read_unlock();
return match;
}
static void update_gid_ip(enum gid_op_type gid_op, static void update_gid_ip(enum gid_op_type gid_op,
struct ib_device *ib_dev, struct ib_device *ib_dev,
u8 port, struct net_device *ndev, u8 port, struct net_device *ndev,
...@@ -391,6 +419,27 @@ static void del_netdev_ips(struct ib_device *ib_dev, u8 port, ...@@ -391,6 +419,27 @@ static void del_netdev_ips(struct ib_device *ib_dev, u8 port,
ib_cache_gid_del_all_netdev_gids(ib_dev, port, cookie); ib_cache_gid_del_all_netdev_gids(ib_dev, port, cookie);
} }
/**
* del_default_gids - Delete default GIDs of the event/cookie netdevice
* @ib_dev: RDMA device pointer
* @port: Port of the RDMA device whose GID table to consider
* @rdma_ndev: Unused rdma netdevice
* @cookie: Pointer to event netdevice
*
* del_default_gids() deletes the default GIDs of the event/cookie netdevice.
*/
static void del_default_gids(struct ib_device *ib_dev, u8 port,
struct net_device *rdma_ndev, void *cookie)
{
struct net_device *cookie_ndev = cookie;
unsigned long gid_type_mask;
gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
ib_cache_gid_set_default_gid(ib_dev, port, cookie_ndev, gid_type_mask,
IB_CACHE_GID_DEFAULT_MODE_DELETE);
}
static void enum_all_gids_of_dev_cb(struct ib_device *ib_dev, static void enum_all_gids_of_dev_cb(struct ib_device *ib_dev,
u8 port, u8 port,
struct net_device *rdma_ndev, struct net_device *rdma_ndev,
...@@ -589,30 +638,34 @@ ndev_event_unlink(struct netdev_notifier_changeupper_info *changeupper_info, ...@@ -589,30 +638,34 @@ ndev_event_unlink(struct netdev_notifier_changeupper_info *changeupper_info,
} }
static void static void
ndev_event_link(struct netdev_notifier_changeupper_info *changeupper_info, ndev_event_link(struct net_device *event_ndev,
struct netdev_notifier_changeupper_info *changeupper_info,
struct netdev_event_work_cmd *cmds) struct netdev_event_work_cmd *cmds)
{ {
static const struct netdev_event_work_cmd static const struct netdev_event_work_cmd
bonding_default_del_cmd = { bonding_default_del_cmd = {
.cb = bond_delete_netdev_default_gids, .cb = del_default_gids,
.filter = is_eth_port_inactive_slave .filter = is_upper_ndev_bond_master_filter
}; };
/* /*
* When a lower netdev is linked to its upper bonding * When a lower netdev is linked to its upper bonding
* netdev, delete lower inactive slave netdev's default GIDs. * netdev, delete lower slave netdev's default GIDs.
*/ */
cmds[0] = bonding_default_del_cmd; cmds[0] = bonding_default_del_cmd;
cmds[0].ndev = changeupper_info->upper_dev; cmds[0].ndev = event_ndev;
cmds[0].filter_ndev = changeupper_info->upper_dev;
cmds[1] = add_cmd_upper_ips; cmds[1] = add_cmd_upper_ips;
cmds[1].ndev = changeupper_info->upper_dev; cmds[1].ndev = changeupper_info->upper_dev;
cmds[1].filter_ndev = changeupper_info->upper_dev; cmds[1].filter_ndev = changeupper_info->upper_dev;
} }
static void netdevice_event_changeupper(struct netdev_notifier_changeupper_info *changeupper_info, static void netdevice_event_changeupper(struct net_device *event_ndev,
struct netdev_notifier_changeupper_info *changeupper_info,
struct netdev_event_work_cmd *cmds) struct netdev_event_work_cmd *cmds)
{ {
if (changeupper_info->linking) if (changeupper_info->linking)
ndev_event_link(changeupper_info, cmds); ndev_event_link(event_ndev, changeupper_info, cmds);
else else
ndev_event_unlink(changeupper_info, cmds); ndev_event_unlink(changeupper_info, cmds);
} }
...@@ -657,7 +710,7 @@ static int netdevice_event(struct notifier_block *this, unsigned long event, ...@@ -657,7 +710,7 @@ static int netdevice_event(struct notifier_block *this, unsigned long event,
break; break;
case NETDEV_CHANGEUPPER: case NETDEV_CHANGEUPPER:
netdevice_event_changeupper( netdevice_event_changeupper(ndev,
container_of(ptr, struct netdev_notifier_changeupper_info, info), container_of(ptr, struct netdev_notifier_changeupper_info, info),
cmds); cmds);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment