From: Junxian Huang huangjunxian6@hisilicon.com
driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I968IB
---------------------------------------------------------------
Currently, a RoCE bond device cannot be recovered to a bond device after reset.
Applying this patch, RoCE bonding device 'hns_bond_xx' can be recovered after reset, including the following changes: 1. modify the condition for juding whether bond_grp is active, as the bond_grp may be also holding HNS_ROCE_CHANGE_BOND during reset init. Thus, as long as the bond_grp's state is not HNS_ROCE_BOND_NOT_BONDED, it should be considered active. 2. update the link status of slave in bond_grp from NIC bonding driver right before sending command to firmware, as RoCE driver is uninited for a while in reset process, and during this period bond_grp cannot update the information. 3. After the reset, re-config the bond_grp information to firmware, as the firmware is also reset and the previous configuration is cleared.
Signed-off-by: Junxian Huang huangjunxian6@hisilicon.com Signed-off-by: Juan Zhou zhoujuan51@h-partners.com --- drivers/infiniband/hw/hns/hns_roce_bond.c | 32 ++++++++++++++++++++--- drivers/infiniband/hw/hns/hns_roce_main.c | 10 +++++-- 2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_bond.c b/drivers/infiniband/hw/hns/hns_roce_bond.c index a35b982ec..6fdd8e9fd 100644 --- a/drivers/infiniband/hw/hns/hns_roce_bond.c +++ b/drivers/infiniband/hw/hns/hns_roce_bond.c @@ -100,9 +100,7 @@ bool hns_roce_bond_is_active(struct hns_roce_dev *hr_dev) { struct hns_roce_bond_group *bond_grp = hns_roce_get_bond_grp(hr_dev);
- if (bond_grp && - (bond_grp->bond_state == HNS_ROCE_BOND_REGISTERING || - bond_grp->bond_state == HNS_ROCE_BOND_IS_BONDED)) + if (bond_grp && bond_grp->bond_state != HNS_ROCE_BOND_NOT_BONDED) return true;
return false; @@ -186,6 +184,13 @@ static void hns_roce_bond_get_active_slave(struct hns_roce_bond_group *bond_grp) bond_grp->active_slave_map = active_slave_map; }
+static int hns_roce_recover_bond(struct hns_roce_bond_group *bond_grp) +{ + hns_roce_bond_get_active_slave(bond_grp); + + return hns_roce_cmd_bond(bond_grp, HNS_ROCE_SET_BOND); +} + static void hns_roce_set_bond(struct hns_roce_bond_group *bond_grp) { struct hns_roce_dev *hr_dev = NULL; @@ -355,6 +360,9 @@ static void hns_roce_do_bond(struct hns_roce_bond_group *bond_grp) enum hns_roce_bond_state bond_state = bond_grp->bond_state; bool bond_ready = bond_grp->bond_ready;
+ if (!bond_grp->main_hr_dev) + return; + ibdev_info(&bond_grp->main_hr_dev->ib_dev, "do_bond: bond_ready - %d, bond_state - %d.\n", bond_ready, bond_grp->bond_state); @@ -403,13 +411,29 @@ void hns_roce_do_bond_work(struct work_struct *work)
int hns_roce_bond_init(struct hns_roce_dev *hr_dev) { + struct hns_roce_bond_group *bond_grp = hns_roce_get_bond_grp(hr_dev); + struct hns_roce_v2_priv *priv = hr_dev->priv; int ret;
+ if (priv->handle->rinfo.reset_state == HNS_ROCE_STATE_RST_INIT && + bond_grp) { + bond_grp->main_hr_dev = hr_dev; + ret = hns_roce_recover_bond(bond_grp); + if (ret) { + ibdev_err(&hr_dev->ib_dev, + "failed to recover RoCE bond, ret = %d.\n", + ret); + return ret; + } + bond_grp->bond_state = HNS_ROCE_BOND_IS_BONDED; + } + hr_dev->bond_nb.notifier_call = hns_roce_bond_event; ret = register_netdevice_notifier(&hr_dev->bond_nb); if (ret) { ibdev_err(&hr_dev->ib_dev, - "failed to register notifier for RoCE bond!\n"); + "failed to register notifier for RoCE bond, ret = %d.\n", + ret); hr_dev->bond_nb.notifier_call = NULL; }
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 3f4316d71..22835c331 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -671,13 +671,19 @@ static void hns_roce_unregister_device(struct hns_roce_dev *hr_dev, bool bond_cleanup) { struct hns_roce_ib_iboe *iboe = &hr_dev->iboe; + struct hns_roce_v2_priv *priv = hr_dev->priv; struct hns_roce_bond_group *bond_grp;
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_BOND) { unregister_netdevice_notifier(&hr_dev->bond_nb); bond_grp = hns_roce_get_bond_grp(hr_dev); - if (bond_grp && bond_cleanup) - hns_roce_cleanup_bond(bond_grp); + if (bond_grp) { + if (bond_cleanup) + hns_roce_cleanup_bond(bond_grp); + else if (priv->handle->rinfo.reset_state == + HNS_ROCE_STATE_RST_UNINIT) + bond_grp->main_hr_dev = NULL; + } }
hr_dev->active = false;