提交 49f27d3e 编写于 作者: J Junxian Huang 提交者: ZhouJuan

RDMA/hns: Support dispatching IB event for RoCE bonding

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6ZAIM

---------------------------------------------------------------

Support dispatching IB event for RoCE bonding. After setting bond,
IB_EVENT_PORT_ERR is dispatched in the following situation:
	1. bond0 becomes link down;
	2. all slaves become link down (as it will lead to a link-down
           of the upper device).

IB_EVENT_PORT_ACTIVE is dispatched in the following situation:
	1. bond0 becomes link up;
	2. one slave becomes link up when all slaves were link down (as
           it will lead to a link-up of the upper device).
Signed-off-by: NJunxian Huang <huangjunxian6@hisilicon.com>
上级 c65db67a
......@@ -136,17 +136,18 @@ struct net_device *hns_roce_get_bond_netdev(struct hns_roce_dev *hr_dev)
if (bond_grp->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
for (i = 0; i < ROCE_BOND_FUNC_MAX; i++) {
net_dev = bond_grp->bond_func_info[i].net_dev;
if (net_dev && is_active_slave(net_dev, bond_grp))
break;
}
} else {
for (i = 0; i < ROCE_BOND_FUNC_MAX; i++) {
net_dev = bond_grp->bond_func_info[i].net_dev;
if (net_dev && get_port_state(net_dev) == IB_PORT_ACTIVE)
break;
if (net_dev && is_active_slave(net_dev, bond_grp) &&
get_port_state(net_dev) == IB_PORT_ACTIVE)
goto out;
}
}
for (i = 0; i < ROCE_BOND_FUNC_MAX; i++) {
net_dev = bond_grp->bond_func_info[i].net_dev;
if (net_dev && get_port_state(net_dev) == IB_PORT_ACTIVE)
break;
}
out:
mutex_unlock(&bond_grp->bond_mutex);
......
......@@ -7570,6 +7570,7 @@ static void hns_roce_hw_v2_link_status_change(struct hnae3_handle *handle,
{
struct net_device *netdev = handle->rinfo.netdev;
struct hns_roce_dev *hr_dev = handle->priv;
struct hns_roce_bond_group *bond_grp;
struct ib_event event;
unsigned long flags;
u8 phy_port;
......@@ -7577,6 +7578,15 @@ static void hns_roce_hw_v2_link_status_change(struct hnae3_handle *handle,
if (linkup || !hr_dev)
return;
/* For bond device, the link status depends on the upper netdev,
* and the upper device's link status depends on all the slaves'
* netdev but not only one. So bond device cannot get a correct
* link status from this path.
*/
bond_grp = hns_roce_get_bond_grp(hr_dev);
if (bond_grp)
return;
for (phy_port = 0; phy_port < hr_dev->caps.num_ports; phy_port++)
if (netdev == hr_dev->iboe.netdevs[phy_port])
break;
......
......@@ -131,17 +131,16 @@ static enum ib_port_state get_upper_port_state(struct hns_roce_dev *hr_dev)
return IB_PORT_ACTIVE;
}
static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
unsigned long dev_event)
static int handle_en_event(struct net_device *netdev,
struct hns_roce_dev *hr_dev,
u32 port, unsigned long dev_event)
{
struct device *dev = hr_dev->dev;
enum ib_port_state port_state;
struct net_device *netdev;
struct ib_event event;
unsigned long flags;
int ret = 0;
netdev = hr_dev->iboe.netdevs[port];
if (!netdev) {
dev_err(dev, "Can't find netdev on port(%u)!\n", port);
return -ENODEV;
......@@ -189,17 +188,24 @@ static int hns_roce_netdev_event(struct notifier_block *self,
unsigned long event, void *ptr)
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct hns_roce_bond_group *bond_grp;
struct hns_roce_ib_iboe *iboe = NULL;
struct hns_roce_dev *hr_dev = NULL;
struct net_device *upper = NULL;
int ret;
u8 port;
hr_dev = container_of(self, struct hns_roce_dev, iboe.nb);
iboe = &hr_dev->iboe;
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_BOND) {
bond_grp = hns_roce_get_bond_grp(hr_dev);
upper = bond_grp ? bond_grp->upper_dev : NULL;
}
for (port = 0; port < hr_dev->caps.num_ports; port++) {
if (dev == iboe->netdevs[port]) {
ret = handle_en_event(hr_dev, port, event);
if ((!upper && dev == iboe->netdevs[port]) ||
(upper && dev == upper)) {
ret = handle_en_event(dev, hr_dev, port, event);
if (ret)
return NOTIFY_DONE;
break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册