Skip to content

Commit 9b44703

Browse files
Yixian Liudledford
authored andcommitted
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 <[email protected]> Signed-off-by: Lijun Ou <[email protected]> Signed-off-by: Wei Hu (Xavier) <[email protected]> Signed-off-by: Shaobo Xu <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent e088a68 commit 9b44703

File tree

5 files changed

+62
-6
lines changed

5 files changed

+62
-6
lines changed

drivers/infiniband/hw/hns/hns_roce_cq.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
315315
struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
316316
struct device *dev = hr_dev->dev;
317317
struct hns_roce_ib_create_cq ucmd;
318+
struct hns_roce_ib_create_cq_resp resp;
318319
struct hns_roce_cq *hr_cq = NULL;
319320
struct hns_roce_uar *uar = NULL;
320321
int vector = attr->comp_vector;
@@ -378,6 +379,16 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
378379
goto err_mtt;
379380
}
380381

382+
if (context && (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
383+
(udata->outlen == sizeof(resp))) {
384+
ret = hns_roce_db_map_user(to_hr_ucontext(context),
385+
ucmd.db_addr, &hr_cq->db);
386+
if (ret) {
387+
dev_err(dev, "cq record doorbell map failed!\n");
388+
goto err_cqc;
389+
}
390+
}
391+
381392
/*
382393
* For the QP created by kernel space, tptr value should be initialized
383394
* 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,
393404
hr_cq->cq_depth = cq_entries;
394405

395406
if (context) {
396-
if (ib_copy_to_udata(udata, &hr_cq->cqn, sizeof(u64))) {
397-
ret = -EFAULT;
398-
goto err_cqc;
399-
}
407+
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
408+
(udata->outlen == sizeof(resp))) {
409+
hr_cq->db_en = 1;
410+
resp.cqn = hr_cq->cqn;
411+
resp.cap_flags |= HNS_ROCE_SUPPORT_CQ_RECORD_DB;
412+
ret = ib_copy_to_udata(udata, &resp, sizeof(resp));
413+
} else
414+
ret = ib_copy_to_udata(udata, &hr_cq->cqn, sizeof(u64));
415+
416+
if (ret)
417+
goto err_dbmap;
400418
}
401419

402420
return &hr_cq->ib_cq;
403421

422+
err_dbmap:
423+
if (context && (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
424+
(udata->outlen == sizeof(resp)))
425+
hns_roce_db_unmap_user(to_hr_ucontext(context),
426+
&hr_cq->db);
427+
404428
err_cqc:
405429
hns_roce_free_cq(hr_dev, hr_cq);
406430

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

433-
if (ib_cq->uobject)
457+
if (ib_cq->uobject) {
434458
ib_umem_release(hr_cq->umem);
435-
else
459+
460+
if (hr_cq->db_en == 1)
461+
hns_roce_db_unmap_user(
462+
to_hr_ucontext(ib_cq->uobject->context),
463+
&hr_cq->db);
464+
} else {
436465
/* Free the buff of stored cq */
437466
hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf,
438467
ib_cq->cqe);
468+
}
439469

440470
kfree(hr_cq);
441471
}

drivers/infiniband/hw/hns/hns_roce_device.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ enum {
109109
HNS_ROCE_SUPPORT_RQ_RECORD_DB = 1 << 0,
110110
};
111111

112+
enum {
113+
HNS_ROCE_SUPPORT_CQ_RECORD_DB = 1 << 0,
114+
};
115+
112116
enum hns_roce_qp_state {
113117
HNS_ROCE_QP_STATE_RST,
114118
HNS_ROCE_QP_STATE_INIT,
@@ -381,6 +385,8 @@ struct hns_roce_cq_buf {
381385
struct hns_roce_cq {
382386
struct ib_cq ib_cq;
383387
struct hns_roce_cq_buf hr_buf;
388+
struct hns_roce_db db;
389+
u8 db_en;
384390
spinlock_t lock;
385391
struct ib_umem *umem;
386392
void (*comp)(struct hns_roce_cq *cq);

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,6 +1638,16 @@ static void hns_roce_v2_write_cqc(struct hns_roce_dev *hr_dev,
16381638
roce_set_field(cq_context->byte_40_cqe_ba, V2_CQC_BYTE_40_CQE_BA_M,
16391639
V2_CQC_BYTE_40_CQE_BA_S, (dma_handle >> (32 + 3)));
16401640

1641+
if (hr_cq->db_en)
1642+
roce_set_bit(cq_context->byte_44_db_record,
1643+
V2_CQC_BYTE_44_DB_RECORD_EN_S, 1);
1644+
1645+
roce_set_field(cq_context->byte_44_db_record,
1646+
V2_CQC_BYTE_44_DB_RECORD_ADDR_M,
1647+
V2_CQC_BYTE_44_DB_RECORD_ADDR_S,
1648+
((u32)hr_cq->db.dma) >> 1);
1649+
cq_context->db_record_addr = hr_cq->db.dma >> 32;
1650+
16411651
roce_set_field(cq_context->byte_56_cqe_period_maxcnt,
16421652
V2_CQC_BYTE_56_CQ_MAX_CNT_M,
16431653
V2_CQC_BYTE_56_CQ_MAX_CNT_S,

drivers/infiniband/hw/hns/hns_roce_hw_v2.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ struct hns_roce_v2_cq_context {
299299

300300
#define V2_CQC_BYTE_44_DB_RECORD_EN_S 0
301301

302+
#define V2_CQC_BYTE_44_DB_RECORD_ADDR_S 1
303+
#define V2_CQC_BYTE_44_DB_RECORD_ADDR_M GENMASK(31, 1)
304+
302305
#define V2_CQC_BYTE_52_CQE_CNT_S 0
303306
#define V2_CQC_BYTE_52_CQE_CNT_M GENMASK(23, 0)
304307

include/uapi/rdma/hns-abi.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838

3939
struct hns_roce_ib_create_cq {
4040
__u64 buf_addr;
41+
__u64 db_addr;
42+
};
43+
44+
struct hns_roce_ib_create_cq_resp {
45+
__u32 cqn;
46+
__u32 reserved;
47+
__u64 cap_flags;
4148
};
4249

4350
struct hns_roce_ib_create_qp {

0 commit comments

Comments
 (0)