RDMA/hns: Support cq record doorbell for the user space
authorYixian Liu <liuyixian@huawei.com>
Fri, 9 Mar 2018 10:36:30 +0000 (18:36 +0800)
committerDoug Ledford <dledford@redhat.com>
Tue, 13 Mar 2018 20:40:15 +0000 (16:40 -0400)
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>
drivers/infiniband/hw/hns/hns_roce_cq.c
drivers/infiniband/hw/hns/hns_roce_device.h
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
drivers/infiniband/hw/hns/hns_roce_hw_v2.h
include/uapi/rdma/hns-abi.h

index bccc9b54c9ce73e8397a5b4c9c2a255d842090e4..8226f19fcdd68f9528251c8f6fe9927dc0f58b98 100644 (file)
@@ -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;
@@ -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
@@ -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);
 
@@ -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);
        }
index aa5cc78244ba15d29277c09fa9a9846c4ffe0787..aacbf18849fcd990e00efaaa5812ac3168998982 100644 (file)
@@ -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,
@@ -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);
index 21575912f739d91a93c3e0f45963d4e3e5816005..bc0a2b7afea9f6cfb86761d82b082639c8089a24 100644 (file)
@@ -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,
index 2bf8a47e3de39618951f94efc2af9dcd9929edb8..182b6726f7838fc83d407eee7d4444fbddf6699d 100644 (file)
@@ -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)
 
index 6150c1941ecae0f636905a0b5d7a0e33c2e1aace..38e8f192bf72bfa9d48676faf0e108bbfb5cc490 100644 (file)
 
 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 {