RDMA/hns: Support cq record doorbell for the user space
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>
This commit is contained in:
parent
e088a685ea
commit
9b44703d0a
|
@ -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 hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
|
||||||
struct device *dev = hr_dev->dev;
|
struct device *dev = hr_dev->dev;
|
||||||
struct hns_roce_ib_create_cq ucmd;
|
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_cq *hr_cq = NULL;
|
||||||
struct hns_roce_uar *uar = NULL;
|
struct hns_roce_uar *uar = NULL;
|
||||||
int vector = attr->comp_vector;
|
int vector = attr->comp_vector;
|
||||||
|
@ -378,6 +379,16 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
|
||||||
goto err_mtt;
|
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
|
* 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
|
* to zero; For the QP created by user space, it will cause synchronous
|
||||||
|
@ -393,14 +404,27 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
|
||||||
hr_cq->cq_depth = cq_entries;
|
hr_cq->cq_depth = cq_entries;
|
||||||
|
|
||||||
if (context) {
|
if (context) {
|
||||||
if (ib_copy_to_udata(udata, &hr_cq->cqn, sizeof(u64))) {
|
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
|
||||||
ret = -EFAULT;
|
(udata->outlen == sizeof(resp))) {
|
||||||
goto err_cqc;
|
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;
|
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:
|
err_cqc:
|
||||||
hns_roce_free_cq(hr_dev, hr_cq);
|
hns_roce_free_cq(hr_dev, hr_cq);
|
||||||
|
|
||||||
|
@ -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_free_cq(hr_dev, hr_cq);
|
||||||
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 (ib_cq->uobject)
|
if (ib_cq->uobject) {
|
||||||
ib_umem_release(hr_cq->umem);
|
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 */
|
/* Free the buff of stored cq */
|
||||||
hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf,
|
hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf,
|
||||||
ib_cq->cqe);
|
ib_cq->cqe);
|
||||||
|
}
|
||||||
|
|
||||||
kfree(hr_cq);
|
kfree(hr_cq);
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,10 @@ enum {
|
||||||
HNS_ROCE_SUPPORT_RQ_RECORD_DB = 1 << 0,
|
HNS_ROCE_SUPPORT_RQ_RECORD_DB = 1 << 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
HNS_ROCE_SUPPORT_CQ_RECORD_DB = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
enum hns_roce_qp_state {
|
enum hns_roce_qp_state {
|
||||||
HNS_ROCE_QP_STATE_RST,
|
HNS_ROCE_QP_STATE_RST,
|
||||||
HNS_ROCE_QP_STATE_INIT,
|
HNS_ROCE_QP_STATE_INIT,
|
||||||
|
@ -381,6 +385,8 @@ struct hns_roce_cq_buf {
|
||||||
struct hns_roce_cq {
|
struct hns_roce_cq {
|
||||||
struct ib_cq ib_cq;
|
struct ib_cq ib_cq;
|
||||||
struct hns_roce_cq_buf hr_buf;
|
struct hns_roce_cq_buf hr_buf;
|
||||||
|
struct hns_roce_db db;
|
||||||
|
u8 db_en;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct ib_umem *umem;
|
struct ib_umem *umem;
|
||||||
void (*comp)(struct hns_roce_cq *cq);
|
void (*comp)(struct hns_roce_cq *cq);
|
||||||
|
|
|
@ -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,
|
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)));
|
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,
|
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_M,
|
||||||
V2_CQC_BYTE_56_CQ_MAX_CNT_S,
|
V2_CQC_BYTE_56_CQ_MAX_CNT_S,
|
||||||
|
|
|
@ -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_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_S 0
|
||||||
#define V2_CQC_BYTE_52_CQE_CNT_M GENMASK(23, 0)
|
#define V2_CQC_BYTE_52_CQE_CNT_M GENMASK(23, 0)
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,13 @@
|
||||||
|
|
||||||
struct hns_roce_ib_create_cq {
|
struct hns_roce_ib_create_cq {
|
||||||
__u64 buf_addr;
|
__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 {
|
struct hns_roce_ib_create_qp {
|
||||||
|
|
Loading…
Reference in New Issue