Commit e9595577 authored by Yixian Liu's avatar Yixian Liu Committed by Jason Gunthorpe

RDMA/hns: Fix cq record doorbell enable in kernel

Upon detecting both kernel and user space support record doorbell,
the kernel needs to enable this capability in hardware by db_en,
and it should take place before cq context configuration in
hns_roce_cq_alloc. Currently, db_en is configured after cq alloc
and db_map_user has similar problem.
Reported-by: default avatarXiping Zhang <zhangxiping3@huawei.com>
Fixes: 9b44703d ("RDMA/hns: Support cq record doorbell for the user space")
Signed-off-by: default avatarYixian Liu <liuyixian@huawei.com>
Signed-off-by: default avatarLijun Ou <oulijun@huawei.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 761fc376
...@@ -355,6 +355,18 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev, ...@@ -355,6 +355,18 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
goto err_cq; goto err_cq;
} }
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
(udata->outlen >= sizeof(resp))) {
ret = hns_roce_db_map_user(to_hr_ucontext(context),
ucmd.db_addr, &hr_cq->db);
if (ret) {
dev_err(dev, "cq record doorbell map failed!\n");
goto err_mtt;
}
hr_cq->db_en = 1;
resp.cap_flags |= HNS_ROCE_SUPPORT_CQ_RECORD_DB;
}
/* Get user space parameters */ /* Get user space parameters */
uar = &to_hr_ucontext(context)->uar; uar = &to_hr_ucontext(context)->uar;
} else { } else {
...@@ -385,17 +397,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev, ...@@ -385,17 +397,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
hr_cq, vector); hr_cq, vector);
if (ret) { if (ret) {
dev_err(dev, "Creat CQ .Failed to cq_alloc.\n"); dev_err(dev, "Creat CQ .Failed to cq_alloc.\n");
goto err_mtt; goto err_dbmap;
}
if (context && (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
(udata->outlen >= sizeof(resp))) {
ret = hns_roce_db_map_user(to_hr_ucontext(context),
ucmd.db_addr, &hr_cq->db);
if (ret) {
dev_err(dev, "cq record doorbell map failed!\n");
goto err_cqc;
}
} }
/* /*
...@@ -414,28 +416,22 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev, ...@@ -414,28 +416,22 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
if (context) { if (context) {
resp.cqn = hr_cq->cqn; resp.cqn = hr_cq->cqn;
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
(udata->outlen >= sizeof(resp))) {
hr_cq->db_en = 1;
resp.cap_flags |= HNS_ROCE_SUPPORT_CQ_RECORD_DB;
}
ret = ib_copy_to_udata(udata, &resp, sizeof(resp)); ret = ib_copy_to_udata(udata, &resp, sizeof(resp));
if (ret) if (ret)
goto err_dbmap; goto err_cqc;
} }
return &hr_cq->ib_cq; return &hr_cq->ib_cq;
err_cqc:
hns_roce_free_cq(hr_dev, hr_cq);
err_dbmap: err_dbmap:
if (context && (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) && if (context && (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
(udata->outlen >= sizeof(resp))) (udata->outlen >= sizeof(resp)))
hns_roce_db_unmap_user(to_hr_ucontext(context), hns_roce_db_unmap_user(to_hr_ucontext(context),
&hr_cq->db); &hr_cq->db);
err_cqc:
hns_roce_free_cq(hr_dev, hr_cq);
err_mtt: err_mtt:
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt); hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
if (context) if (context)
......
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