From: Junxian Huang huangjunxian6@hisilicon.com
driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8N6RR
----------------------------------------------------------------------
During slave increase event (a new slave being added to a existing bond), the existing slaves do not have a corresponding hr_dev handle (except for the main_hr_dev one). These slaves are mistakenly treated as non-hns devices and will lead to bond clear currently.
The correct way to confirm if a slave is a hns device is to compare the netdev handle saved in the bond group.
Fixes: 6ba084e0f031 ("RDMA/hns: add constraints for bonding-unsupported situations") 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 | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_bond.c b/drivers/infiniband/hw/hns/hns_roce_bond.c index 2923acb810bd..238914c58869 100644 --- a/drivers/infiniband/hw/hns/hns_roce_bond.c +++ b/drivers/infiniband/hw/hns/hns_roce_bond.c @@ -790,9 +790,20 @@ static struct hns_roce_bond_group *hns_roce_alloc_bond_grp(struct hns_roce_dev * return bond_grp; }
-static bool is_dev_bond_supported(struct hns_roce_dev *hr_dev, int bus_num) +static bool is_dev_bond_supported(struct hns_roce_bond_group *bond_grp, + struct net_device *net_dev, int bus_num) { - if (!hr_dev || !(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_BOND)) + struct hns_roce_dev *hr_dev = hns_roce_get_hrdev_by_netdev(net_dev); + + if (!hr_dev) { + if (bond_grp && + get_netdev_bond_slave_id(net_dev, bond_grp) >= 0) + return true; + else + return false; + } + + if (!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_BOND)) return false;
if (hr_dev->is_vf || pci_num_vf(hr_dev->pci_dev) > 0) @@ -820,10 +831,10 @@ static bool check_unlinking_bond_support(struct hns_roce_bond_group *bond_grp) }
static bool check_linking_bond_support(struct netdev_lag_upper_info *bond_info, + struct hns_roce_bond_group *bond_grp, struct net_device *upper_dev, int bus_num) { - struct hns_roce_dev *hr_dev; struct net_device *net_dev; u8 slave_num = 0;
@@ -832,8 +843,7 @@ static bool check_linking_bond_support(struct netdev_lag_upper_info *bond_info,
rcu_read_lock(); for_each_netdev_in_bond_rcu(upper_dev, net_dev) { - hr_dev = hns_roce_get_hrdev_by_netdev(net_dev); - if (is_dev_bond_supported(hr_dev, bus_num)) { + if (is_dev_bond_supported(bond_grp, net_dev, bus_num)) { slave_num++; } else { rcu_read_unlock(); @@ -865,7 +875,7 @@ static enum bond_support_type return BOND_NOT_SUPPORT;
if (info->linking) - support = check_linking_bond_support(info->upper_info, + support = check_linking_bond_support(info->upper_info, bond_grp, *upper_dev, bus_num); else support = check_unlinking_bond_support(bond_grp);