diff --git a/drivers/infiniband/hw/hns/hns_roce_bond.c b/drivers/infiniband/hw/hns/hns_roce_bond.c index 146eeb7f483bcf0d960f23e0b96b9dd22f01e0cb..4b2b5538c918e444b41e66664189524ffad8b75f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_bond.c +++ b/drivers/infiniband/hw/hns/hns_roce_bond.c @@ -629,6 +629,7 @@ int hns_roce_cleanup_bond(struct hns_roce_bond_group *bond_grp) completion_no_waiter = completion_done(&bond_grp->bond_work_done); complete(&bond_grp->bond_work_done); + mutex_destroy(&bond_grp->bond_mutex); if (completion_no_waiter) kfree(bond_grp); @@ -780,6 +781,7 @@ static struct hns_roce_bond_group *hns_roce_alloc_bond_grp(struct hns_roce_dev * if (ret) { ibdev_err(&main_hr_dev->ib_dev, "failed to alloc bond ID, ret = %d.\n", ret); + mutex_destroy(&bond_grp->bond_mutex); kfree(bond_grp); return NULL; } diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 033d2922515355c37aa88cfc071ec75d2c7cd167..6c5630c56eb784fde0af598839b1c0302bb99cee 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -1453,8 +1453,6 @@ struct hns_user_mmap_entry * hns_roce_user_mmap_entry_insert(struct ib_ucontext *ucontext, u64 address, size_t length, enum hns_roce_mmap_type mmap_type); -void hns_roce_register_sysfs(struct hns_roce_dev *hr_dev); -void hns_roce_unregister_sysfs(struct hns_roce_dev *hr_dev); void hns_roce_add_unfree_umem(struct hns_roce_user_db_page *user_page, struct hns_roce_dev *hr_dev); void hns_roce_free_unfree_umem(struct hns_roce_dev *hr_dev); @@ -1462,4 +1460,6 @@ void hns_roce_add_unfree_mtr(struct hns_roce_mtr_node *pos, struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr); void hns_roce_free_unfree_mtr(struct hns_roce_dev *hr_dev); +int hns_roce_alloc_scc_param(struct hns_roce_dev *hr_dev); +void hns_roce_dealloc_scc_param(struct hns_roce_dev *hr_dev); #endif /* _HNS_ROCE_DEVICE_H */ diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 2d4560c9f249f99319fa9ff5ebf7eecea1c1bc33..86454de85d619295ad9f1d8bc19ba32edb93f7da 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -316,9 +316,10 @@ static int hns_roce_query_port(struct ib_device *ib_dev, u32 port_num, if (ret) ibdev_warn(ib_dev, "failed to get speed, ret = %d.\n", ret); + net_dev = hr_dev->hw->get_bond_netdev(hr_dev); + spin_lock_irqsave(&hr_dev->iboe.lock, flags); - net_dev = hr_dev->hw->get_bond_netdev(hr_dev); if (!net_dev) net_dev = get_hr_netdev(hr_dev, port); if (!net_dev) { @@ -1319,6 +1320,7 @@ static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev) if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_CQ_RECORD_DB || hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_QP_RECORD_DB) mutex_destroy(&hr_dev->pgdir_mutex); + mutex_destroy(&hr_dev->uctx_list_mutex); return ret; } @@ -1447,16 +1449,21 @@ int hns_roce_init(struct hns_roce_dev *hr_dev) } } + ret = hns_roce_alloc_scc_param(hr_dev); + if (ret) + dev_err(hr_dev->dev, "alloc scc param failed, ret = %d!\n", + ret); + ret = hns_roce_register_device(hr_dev); if (ret) goto error_failed_register_device; - hns_roce_register_sysfs(hr_dev); hns_roce_register_debugfs(hr_dev); return 0; error_failed_register_device: + hns_roce_dealloc_scc_param(hr_dev); if (hr_dev->hw->hw_exit) hr_dev->hw->hw_exit(hr_dev); @@ -1486,8 +1493,8 @@ int hns_roce_init(struct hns_roce_dev *hr_dev) void hns_roce_exit(struct hns_roce_dev *hr_dev, bool bond_cleanup) { - hns_roce_unregister_sysfs(hr_dev); hns_roce_unregister_device(hr_dev, bond_cleanup); + hns_roce_dealloc_scc_param(hr_dev); hns_roce_unregister_debugfs(hr_dev); if (hr_dev->hw->hw_exit) diff --git a/drivers/infiniband/hw/hns/hns_roce_sysfs.c b/drivers/infiniband/hw/hns/hns_roce_sysfs.c index a9708d28a0892480e2f842b5b8b2b137dab4c0de..d36f05ac5f1e73c0e69ab452225fae33e0505b58 100644 --- a/drivers/infiniband/hw/hns/hns_roce_sysfs.c +++ b/drivers/infiniband/hw/hns/hns_roce_sysfs.c @@ -33,7 +33,7 @@ static void get_default_scc_param(struct hns_roce_dev *hr_dev) } } -static int alloc_scc_param(struct hns_roce_dev *hr_dev) +int hns_roce_alloc_scc_param(struct hns_roce_dev *hr_dev) { struct hns_roce_scc_param *scc_param; int i; @@ -56,6 +56,19 @@ static int alloc_scc_param(struct hns_roce_dev *hr_dev) return 0; } +void hns_roce_dealloc_scc_param(struct hns_roce_dev *hr_dev) +{ + int i; + + if (!hr_dev->scc_param) + return; + + for (i = 0; i < HNS_ROCE_SCC_ALGO_TOTAL; i++) + cancel_delayed_work_sync(&hr_dev->scc_param[i].scc_cfg_dwork); + + kvfree(hr_dev->scc_param); + hr_dev->scc_param = NULL; +} struct hns_port_cc_attr { struct ib_port_attribute port_attr; @@ -158,11 +171,14 @@ static umode_t scc_attr_is_visible(struct kobject *kobj, struct ib_device *ibdev = ib_port_sysfs_get_ibdev_kobj(kobj, &port_num); struct hns_roce_dev *hr_dev = to_hr_dev(ibdev); + if (!hr_dev->scc_param) + return 0; + if (hr_dev->is_vf || !(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL)) return 0; - if (!(hr_dev->caps.default_cong_type & (1 << scc_attr->algo_type))) + if (!(hr_dev->caps.cong_cap & (1 << scc_attr->algo_type))) return 0; return 0644; @@ -328,19 +344,3 @@ const struct attribute_group *hns_attr_port_groups[] = { &dip_cc_param_group, NULL, }; - -void hns_roce_register_sysfs(struct hns_roce_dev *hr_dev) -{ - int ret; - - ret = alloc_scc_param(hr_dev); - if (ret) - dev_err(hr_dev->dev, "alloc scc param failed, ret = %d!\n", - ret); -} - -void hns_roce_unregister_sysfs(struct hns_roce_dev *hr_dev) -{ - if (hr_dev->scc_param) - kvfree(hr_dev->scc_param); -}