Commit 58c4f0d8 authored by oulijun's avatar oulijun Committed by Doug Ledford

IB/hns: Fix the bug with wild pointer when destroy rc qp

When destroyed rc qp, the hr_qp will be used after freed. This patch
will fix it.
Signed-off-by: default avatarLijun Ou <oulijun@huawei.com>
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 5802883d
...@@ -3657,6 +3657,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work) ...@@ -3657,6 +3657,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
struct hns_roce_dev *hr_dev; struct hns_roce_dev *hr_dev;
struct hns_roce_qp *hr_qp; struct hns_roce_qp *hr_qp;
struct device *dev; struct device *dev;
unsigned long qpn;
int ret; int ret;
qp_work_entry = container_of(work, struct hns_roce_qp_work, work); qp_work_entry = container_of(work, struct hns_roce_qp_work, work);
...@@ -3664,8 +3665,9 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work) ...@@ -3664,8 +3665,9 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
dev = &hr_dev->pdev->dev; dev = &hr_dev->pdev->dev;
priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv; priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
hr_qp = qp_work_entry->qp; hr_qp = qp_work_entry->qp;
qpn = hr_qp->qpn;
dev_dbg(dev, "Schedule destroy QP(0x%lx) work.\n", hr_qp->qpn); dev_dbg(dev, "Schedule destroy QP(0x%lx) work.\n", qpn);
qp_work_entry->sche_cnt++; qp_work_entry->sche_cnt++;
...@@ -3676,7 +3678,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work) ...@@ -3676,7 +3678,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
&qp_work_entry->db_wait_stage); &qp_work_entry->db_wait_stage);
if (ret) { if (ret) {
dev_err(dev, "Check QP(0x%lx) db process status failed!\n", dev_err(dev, "Check QP(0x%lx) db process status failed!\n",
hr_qp->qpn); qpn);
return; return;
} }
...@@ -3690,7 +3692,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work) ...@@ -3690,7 +3692,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
ret = hns_roce_v1_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state, ret = hns_roce_v1_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state,
IB_QPS_RESET); IB_QPS_RESET);
if (ret) { if (ret) {
dev_err(dev, "Modify QP(0x%lx) to RST failed!\n", hr_qp->qpn); dev_err(dev, "Modify QP(0x%lx) to RST failed!\n", qpn);
return; return;
} }
...@@ -3699,14 +3701,14 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work) ...@@ -3699,14 +3701,14 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
if (hr_qp->ibqp.qp_type == IB_QPT_RC) { if (hr_qp->ibqp.qp_type == IB_QPT_RC) {
/* RC QP, release QPN */ /* RC QP, release QPN */
hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1); hns_roce_release_range_qp(hr_dev, qpn, 1);
kfree(hr_qp); kfree(hr_qp);
} else } else
kfree(hr_to_hr_sqp(hr_qp)); kfree(hr_to_hr_sqp(hr_qp));
kfree(qp_work_entry); kfree(qp_work_entry);
dev_dbg(dev, "Accomplished destroy QP(0x%lx) work.\n", hr_qp->qpn); dev_dbg(dev, "Accomplished destroy QP(0x%lx) work.\n", qpn);
} }
int hns_roce_v1_destroy_qp(struct ib_qp *ibqp) int hns_roce_v1_destroy_qp(struct ib_qp *ibqp)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment