Skip to content

Commit

Permalink
RDMA/hns: Support cq record doorbell for the user space
Browse files Browse the repository at this point in the history
This patch updates to support cq record doorbell for
the user space.

Signed-off-by: Yixian Liu <liuyixian@huawei.com>
Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Shaobo Xu <xushaobo2@huawei.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
  • Loading branch information
Yixian Liu authored and Doug Ledford committed Mar 13, 2018
1 parent e088a68 commit 9b44703
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 6 deletions.
42 changes: 36 additions & 6 deletions drivers/infiniband/hw/hns/hns_roce_cq.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
struct device *dev = hr_dev->dev;
struct hns_roce_ib_create_cq ucmd;
struct hns_roce_ib_create_cq_resp resp;
struct hns_roce_cq *hr_cq = NULL;
struct hns_roce_uar *uar = NULL;
int vector = attr->comp_vector;
Expand Down Expand Up @@ -378,6 +379,16 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
goto err_mtt;
}

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;
}
}

/*
* For the QP created by kernel space, tptr value should be initialized
* to zero; For the QP created by user space, it will cause synchronous
Expand All @@ -393,14 +404,27 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
hr_cq->cq_depth = cq_entries;

if (context) {
if (ib_copy_to_udata(udata, &hr_cq->cqn, sizeof(u64))) {
ret = -EFAULT;
goto err_cqc;
}
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
(udata->outlen == sizeof(resp))) {
hr_cq->db_en = 1;
resp.cqn = hr_cq->cqn;
resp.cap_flags |= HNS_ROCE_SUPPORT_CQ_RECORD_DB;
ret = ib_copy_to_udata(udata, &resp, sizeof(resp));
} else
ret = ib_copy_to_udata(udata, &hr_cq->cqn, sizeof(u64));

if (ret)
goto err_dbmap;
}

return &hr_cq->ib_cq;

err_dbmap:
if (context && (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
(udata->outlen == sizeof(resp)))
hns_roce_db_unmap_user(to_hr_ucontext(context),
&hr_cq->db);

err_cqc:
hns_roce_free_cq(hr_dev, hr_cq);

Expand Down Expand Up @@ -430,12 +454,18 @@ int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq)
hns_roce_free_cq(hr_dev, hr_cq);
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);

if (ib_cq->uobject)
if (ib_cq->uobject) {
ib_umem_release(hr_cq->umem);
else

if (hr_cq->db_en == 1)
hns_roce_db_unmap_user(
to_hr_ucontext(ib_cq->uobject->context),
&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);
}

kfree(hr_cq);
}
Expand Down
6 changes: 6 additions & 0 deletions drivers/infiniband/hw/hns/hns_roce_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ enum {
HNS_ROCE_SUPPORT_RQ_RECORD_DB = 1 << 0,
};

enum {
HNS_ROCE_SUPPORT_CQ_RECORD_DB = 1 << 0,
};

enum hns_roce_qp_state {
HNS_ROCE_QP_STATE_RST,
HNS_ROCE_QP_STATE_INIT,
Expand Down Expand Up @@ -381,6 +385,8 @@ struct hns_roce_cq_buf {
struct hns_roce_cq {
struct ib_cq ib_cq;
struct hns_roce_cq_buf hr_buf;
struct hns_roce_db db;
u8 db_en;
spinlock_t lock;
struct ib_umem *umem;
void (*comp)(struct hns_roce_cq *cq);
Expand Down
10 changes: 10 additions & 0 deletions drivers/infiniband/hw/hns/hns_roce_hw_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,16 @@ static void hns_roce_v2_write_cqc(struct hns_roce_dev *hr_dev,
roce_set_field(cq_context->byte_40_cqe_ba, V2_CQC_BYTE_40_CQE_BA_M,
V2_CQC_BYTE_40_CQE_BA_S, (dma_handle >> (32 + 3)));

if (hr_cq->db_en)
roce_set_bit(cq_context->byte_44_db_record,
V2_CQC_BYTE_44_DB_RECORD_EN_S, 1);

roce_set_field(cq_context->byte_44_db_record,
V2_CQC_BYTE_44_DB_RECORD_ADDR_M,
V2_CQC_BYTE_44_DB_RECORD_ADDR_S,
((u32)hr_cq->db.dma) >> 1);
cq_context->db_record_addr = hr_cq->db.dma >> 32;

roce_set_field(cq_context->byte_56_cqe_period_maxcnt,
V2_CQC_BYTE_56_CQ_MAX_CNT_M,
V2_CQC_BYTE_56_CQ_MAX_CNT_S,
Expand Down
3 changes: 3 additions & 0 deletions drivers/infiniband/hw/hns/hns_roce_hw_v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ struct hns_roce_v2_cq_context {

#define V2_CQC_BYTE_44_DB_RECORD_EN_S 0

#define V2_CQC_BYTE_44_DB_RECORD_ADDR_S 1
#define V2_CQC_BYTE_44_DB_RECORD_ADDR_M GENMASK(31, 1)

#define V2_CQC_BYTE_52_CQE_CNT_S 0
#define V2_CQC_BYTE_52_CQE_CNT_M GENMASK(23, 0)

Expand Down
7 changes: 7 additions & 0 deletions include/uapi/rdma/hns-abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@

struct hns_roce_ib_create_cq {
__u64 buf_addr;
__u64 db_addr;
};

struct hns_roce_ib_create_cq_resp {
__u32 cqn;
__u32 reserved;
__u64 cap_flags;
};

struct hns_roce_ib_create_qp {
Expand Down

0 comments on commit 9b44703

Please sign in to comment.