Commit 9a8ae930 authored by Yuyu Li's avatar Yuyu Li Committed by Junxian Huang
Browse files

RDMA/hns: Fix remove debugfs after device has been unregistered

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



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

hns_roce_unregister_device() will be problematic if it is
in front of hns_roce_unregister_debugfs(),
hns_roce_unregister_device() will free up ib_deivce, and
there will be a risk if debugfs uses ib_deivce. Conversely,
if hns_roce_unregister_debugfs() is in front of
hns_roce_unregister_device(), when the driver is uninstalled,
the former will delete the entire debugfs directory, and the
latter will destroy all the debugfs subdirectories of uctx,
and an error will occur because the debugfs directory of uctx
no longer exists.

Now put hns_roce_unregister_debugfs() in front of
hns_roce_unregister_device () and leave the all debugfs root
NULL after hns_roce_unregister_debugfs(), so that call
hns_roce_unregister_device () again, if the debugfs directory
of uctx is determined to be empty, return it directly without
throwing an error. The above problems can be solved in this
patch.

Fixes: 640cb088 ("RDMA/hns: Add debugfs support for DCA")
Signed-off-by: default avatarYuyu Li <liyuyu6@huawei.com>
Signed-off-by: default avatarXinghai Cen <cenxinghai@h-partners.com>
parent e791a511
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -486,9 +486,14 @@ void hns_roce_register_uctx_debugfs(struct hns_roce_dev *hr_dev,
				     hr_dev, uctx);
}

void hns_roce_unregister_uctx_debugfs(struct hns_roce_ucontext *uctx)
void hns_roce_unregister_uctx_debugfs(struct hns_roce_dev *hr_dev,
					struct hns_roce_ucontext *uctx)
{
	debugfs_remove_recursive(uctx->dca_dbgfs.root);
	struct hns_dca_debugfs *dca_dbgfs = &hr_dev->dbgfs.dca_root;
	char name[DCA_CTX_PID_LEN];

	snprintf(name, sizeof(name), "%d", uctx->pid);
	debugfs_lookup_and_remove(name, dca_dbgfs->root);
}

/* debugfs for device */
@@ -508,6 +513,7 @@ void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev)
void hns_roce_unregister_debugfs(struct hns_roce_dev *hr_dev)
{
	debugfs_remove_recursive(hr_dev->dbgfs.root);
	memset(&hr_dev->dbgfs, 0, sizeof(hr_dev->dbgfs));
}

/* debugfs for hns module */
+2 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev);
void hns_roce_unregister_debugfs(struct hns_roce_dev *hr_dev);
void hns_roce_register_uctx_debugfs(struct hns_roce_dev *hr_dev,
				    struct hns_roce_ucontext *uctx);
void hns_roce_unregister_uctx_debugfs(struct hns_roce_ucontext *uctx);
void hns_roce_unregister_uctx_debugfs(struct hns_roce_dev *hr_dev,
					struct hns_roce_ucontext *uctx);

#endif
+2 −2
Original line number Diff line number Diff line
@@ -633,7 +633,7 @@ static void hns_roce_dealloc_ucontext(struct ib_ucontext *ibcontext)
	struct hns_roce_dev *hr_dev = to_hr_dev(ibcontext->device);

	hns_roce_put_cq_bankid_for_uctx(context);
	hns_roce_unregister_uctx_debugfs(context);
	hns_roce_unregister_uctx_debugfs(hr_dev, context);

	mutex_lock(&hr_dev->uctx_list_mutex);
	list_del(&context->list);
@@ -1494,9 +1494,9 @@ 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_debugfs(hr_dev);
	hns_roce_unregister_device(hr_dev, bond_cleanup);
	hns_roce_dealloc_scc_param(hr_dev);
	hns_roce_unregister_debugfs(hr_dev);

	hns_roce_free_dca_safe_buf(hr_dev);