Commit 62d059b9 authored by Junxian Huang's avatar Junxian Huang Committed by Juan Zhou
Browse files

RDMA/hns: Support reset recovery for RoCE bonding

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: default avatarJunxian Huang <huangjunxian6@hisilicon.com>
Signed-off-by: default avatarJuan Zhou <zhoujuan51@h-partners.com>
parent f4968053
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -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;
	}

+8 −2
Original line number Diff line number Diff line
@@ -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)
		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;