RDMA: Clean destroy CQ in drivers do not return errors
Like all other destroy commands, .destroy_cq() call is not supposed to fail. In all flows, the attempt to return earlier caused to memory leaks. This patch converts .destroy_cq() to do not return any errors. Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Acked-by: Gal Pressman <galpress@amazon.com> Acked-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
这个提交包含在:
@@ -443,40 +443,36 @@ err_cq:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_ib_create_cq);
|
||||
|
||||
int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
|
||||
void hns_roce_ib_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
|
||||
struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
|
||||
int ret = 0;
|
||||
|
||||
if (hr_dev->hw->destroy_cq) {
|
||||
ret = hr_dev->hw->destroy_cq(ib_cq, udata);
|
||||
} else {
|
||||
hns_roce_free_cq(hr_dev, hr_cq);
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
|
||||
|
||||
if (udata) {
|
||||
ib_umem_release(hr_cq->umem);
|
||||
|
||||
if (hr_cq->db_en == 1)
|
||||
hns_roce_db_unmap_user(
|
||||
rdma_udata_to_drv_context(
|
||||
udata,
|
||||
struct hns_roce_ucontext,
|
||||
ibucontext),
|
||||
&hr_cq->db);
|
||||
} else {
|
||||
/* Free the buff of stored cq */
|
||||
hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf,
|
||||
ib_cq->cqe);
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)
|
||||
hns_roce_free_db(hr_dev, &hr_cq->db);
|
||||
}
|
||||
|
||||
kfree(hr_cq);
|
||||
hr_dev->hw->destroy_cq(ib_cq, udata);
|
||||
return;
|
||||
}
|
||||
|
||||
return ret;
|
||||
hns_roce_free_cq(hr_dev, hr_cq);
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
|
||||
|
||||
if (udata) {
|
||||
ib_umem_release(hr_cq->umem);
|
||||
|
||||
if (hr_cq->db_en == 1)
|
||||
hns_roce_db_unmap_user(rdma_udata_to_drv_context(
|
||||
udata,
|
||||
struct hns_roce_ucontext,
|
||||
ibucontext),
|
||||
&hr_cq->db);
|
||||
} else {
|
||||
/* Free the buff of stored cq */
|
||||
hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf, ib_cq->cqe);
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)
|
||||
hns_roce_free_db(hr_dev, &hr_cq->db);
|
||||
}
|
||||
|
||||
kfree(hr_cq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_ib_destroy_cq);
|
||||
|
||||
|
@@ -938,7 +938,7 @@ struct hns_roce_hw {
|
||||
int (*poll_cq)(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
|
||||
int (*dereg_mr)(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr,
|
||||
struct ib_udata *udata);
|
||||
int (*destroy_cq)(struct ib_cq *ibcq, struct ib_udata *udata);
|
||||
void (*destroy_cq)(struct ib_cq *ibcq, struct ib_udata *udata);
|
||||
int (*modify_cq)(struct ib_cq *cq, u16 cq_count, u16 cq_period);
|
||||
int (*init_eq)(struct hns_roce_dev *hr_dev);
|
||||
void (*cleanup_eq)(struct hns_roce_dev *hr_dev);
|
||||
@@ -1209,7 +1209,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
|
||||
const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
|
||||
int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
|
||||
void hns_roce_ib_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
|
||||
void hns_roce_free_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq);
|
||||
|
||||
int hns_roce_db_map_user(struct hns_roce_ucontext *context,
|
||||
|
@@ -865,8 +865,7 @@ alloc_pd_failed:
|
||||
kfree(pd);
|
||||
|
||||
alloc_mem_failed:
|
||||
if (hns_roce_ib_destroy_cq(cq, NULL))
|
||||
dev_err(dev, "Destroy cq for create_lp_qp failed!\n");
|
||||
hns_roce_ib_destroy_cq(cq, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -894,10 +893,7 @@ static void hns_roce_v1_release_lp_qp(struct hns_roce_dev *hr_dev)
|
||||
i, ret);
|
||||
}
|
||||
|
||||
ret = hns_roce_ib_destroy_cq(&free_mr->mr_free_cq->ib_cq, NULL);
|
||||
if (ret)
|
||||
dev_err(dev, "Destroy cq for mr_free failed(%d)!\n", ret);
|
||||
|
||||
hns_roce_ib_destroy_cq(&free_mr->mr_free_cq->ib_cq, NULL);
|
||||
hns_roce_dealloc_pd(&free_mr->mr_free_pd->ibpd, NULL);
|
||||
}
|
||||
|
||||
@@ -3654,7 +3650,7 @@ int hns_roce_v1_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
|
||||
static void hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibcq->device);
|
||||
struct hns_roce_cq *hr_cq = to_hr_cq(ibcq);
|
||||
@@ -3663,7 +3659,6 @@ static int hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
|
||||
u32 cqe_cnt_cur;
|
||||
u32 cq_buf_size;
|
||||
int wait_time = 0;
|
||||
int ret = 0;
|
||||
|
||||
hns_roce_free_cq(hr_dev, hr_cq);
|
||||
|
||||
@@ -3685,7 +3680,6 @@ static int hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
|
||||
if (wait_time > HNS_ROCE_MAX_FREE_CQ_WAIT_CNT) {
|
||||
dev_warn(dev, "Destroy cq 0x%lx timeout!\n",
|
||||
hr_cq->cqn);
|
||||
ret = -ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
wait_time++;
|
||||
@@ -3702,8 +3696,6 @@ static int hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
|
||||
}
|
||||
|
||||
kfree(hr_cq);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void set_eq_cons_index_v1(struct hns_roce_eq *eq, int req_not)
|
||||
|
在新工单中引用
屏蔽一个用户