Skip to content

Commit 287f329

Browse files
yaminfChristoph Hellwig
authored andcommitted
nvme-rdma: use new shared CQ mechanism
Has the driver use shared CQs providing ~10%-20% improvement as seen in the patch introducing shared CQs. Instead of opening a CQ for each QP per controller connected, a CQ for each QP will be provided by the RDMA core driver that will be shared between the QPs on that core reducing interrupt overhead. Signed-off-by: Yamin Friedman <[email protected]> Signed-off-by: Max Gurtovoy <[email protected]> Reviewed-by: Or Gerlitz <[email protected]> Reviewed-by: Sagi Grimberg <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent df4f9bc commit 287f329

File tree

1 file changed

+51
-26
lines changed

1 file changed

+51
-26
lines changed

drivers/nvme/host/rdma.c

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ struct nvme_rdma_queue {
9696
int cm_error;
9797
struct completion cm_done;
9898
bool pi_support;
99+
int cq_size;
99100
};
100101

101102
struct nvme_rdma_ctrl {
@@ -275,6 +276,7 @@ static int nvme_rdma_create_qp(struct nvme_rdma_queue *queue, const int factor)
275276
init_attr.recv_cq = queue->ib_cq;
276277
if (queue->pi_support)
277278
init_attr.create_flags |= IB_QP_CREATE_INTEGRITY_EN;
279+
init_attr.qp_context = queue;
278280

279281
ret = rdma_create_qp(queue->cm_id, dev->pd, &init_attr);
280282

@@ -409,6 +411,14 @@ nvme_rdma_find_get_device(struct rdma_cm_id *cm_id)
409411
return NULL;
410412
}
411413

414+
static void nvme_rdma_free_cq(struct nvme_rdma_queue *queue)
415+
{
416+
if (nvme_rdma_poll_queue(queue))
417+
ib_free_cq(queue->ib_cq);
418+
else
419+
ib_cq_pool_put(queue->ib_cq, queue->cq_size);
420+
}
421+
412422
static void nvme_rdma_destroy_queue_ib(struct nvme_rdma_queue *queue)
413423
{
414424
struct nvme_rdma_device *dev;
@@ -430,7 +440,7 @@ static void nvme_rdma_destroy_queue_ib(struct nvme_rdma_queue *queue)
430440
* the destruction of the QP shouldn't use rdma_cm API.
431441
*/
432442
ib_destroy_qp(queue->qp);
433-
ib_free_cq(queue->ib_cq);
443+
nvme_rdma_free_cq(queue);
434444

435445
nvme_rdma_free_ring(ibdev, queue->rsp_ring, queue->queue_size,
436446
sizeof(struct nvme_completion), DMA_FROM_DEVICE);
@@ -450,13 +460,42 @@ static int nvme_rdma_get_max_fr_pages(struct ib_device *ibdev, bool pi_support)
450460
return min_t(u32, NVME_RDMA_MAX_SEGMENTS, max_page_list_len - 1);
451461
}
452462

463+
static int nvme_rdma_create_cq(struct ib_device *ibdev,
464+
struct nvme_rdma_queue *queue)
465+
{
466+
int ret, comp_vector, idx = nvme_rdma_queue_idx(queue);
467+
enum ib_poll_context poll_ctx;
468+
469+
/*
470+
* Spread I/O queues completion vectors according their queue index.
471+
* Admin queues can always go on completion vector 0.
472+
*/
473+
comp_vector = (idx == 0 ? idx : idx - 1) % ibdev->num_comp_vectors;
474+
475+
/* Polling queues need direct cq polling context */
476+
if (nvme_rdma_poll_queue(queue)) {
477+
poll_ctx = IB_POLL_DIRECT;
478+
queue->ib_cq = ib_alloc_cq(ibdev, queue, queue->cq_size,
479+
comp_vector, poll_ctx);
480+
} else {
481+
poll_ctx = IB_POLL_SOFTIRQ;
482+
queue->ib_cq = ib_cq_pool_get(ibdev, queue->cq_size,
483+
comp_vector, poll_ctx);
484+
}
485+
486+
if (IS_ERR(queue->ib_cq)) {
487+
ret = PTR_ERR(queue->ib_cq);
488+
return ret;
489+
}
490+
491+
return 0;
492+
}
493+
453494
static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
454495
{
455496
struct ib_device *ibdev;
456497
const int send_wr_factor = 3; /* MR, SEND, INV */
457498
const int cq_factor = send_wr_factor + 1; /* + RECV */
458-
int comp_vector, idx = nvme_rdma_queue_idx(queue);
459-
enum ib_poll_context poll_ctx;
460499
int ret, pages_per_mr;
461500

462501
queue->device = nvme_rdma_find_get_device(queue->cm_id);
@@ -467,26 +506,12 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
467506
}
468507
ibdev = queue->device->dev;
469508

470-
/*
471-
* Spread I/O queues completion vectors according their queue index.
472-
* Admin queues can always go on completion vector 0.
473-
*/
474-
comp_vector = (idx == 0 ? idx : idx - 1) % ibdev->num_comp_vectors;
475-
476-
/* Polling queues need direct cq polling context */
477-
if (nvme_rdma_poll_queue(queue))
478-
poll_ctx = IB_POLL_DIRECT;
479-
else
480-
poll_ctx = IB_POLL_SOFTIRQ;
481-
482509
/* +1 for ib_stop_cq */
483-
queue->ib_cq = ib_alloc_cq(ibdev, queue,
484-
cq_factor * queue->queue_size + 1,
485-
comp_vector, poll_ctx);
486-
if (IS_ERR(queue->ib_cq)) {
487-
ret = PTR_ERR(queue->ib_cq);
510+
queue->cq_size = cq_factor * queue->queue_size + 1;
511+
512+
ret = nvme_rdma_create_cq(ibdev, queue);
513+
if (ret)
488514
goto out_put_dev;
489-
}
490515

491516
ret = nvme_rdma_create_qp(queue, send_wr_factor);
492517
if (ret)
@@ -512,7 +537,7 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
512537
if (ret) {
513538
dev_err(queue->ctrl->ctrl.device,
514539
"failed to initialize MR pool sized %d for QID %d\n",
515-
queue->queue_size, idx);
540+
queue->queue_size, nvme_rdma_queue_idx(queue));
516541
goto out_destroy_ring;
517542
}
518543

@@ -523,7 +548,7 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
523548
if (ret) {
524549
dev_err(queue->ctrl->ctrl.device,
525550
"failed to initialize PI MR pool sized %d for QID %d\n",
526-
queue->queue_size, idx);
551+
queue->queue_size, nvme_rdma_queue_idx(queue));
527552
goto out_destroy_mr_pool;
528553
}
529554
}
@@ -540,7 +565,7 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
540565
out_destroy_qp:
541566
rdma_destroy_qp(queue->cm_id);
542567
out_destroy_ib_cq:
543-
ib_free_cq(queue->ib_cq);
568+
nvme_rdma_free_cq(queue);
544569
out_put_dev:
545570
nvme_rdma_dev_put(queue->device);
546571
return ret;
@@ -1163,7 +1188,7 @@ static void nvme_rdma_end_request(struct nvme_rdma_request *req)
11631188
static void nvme_rdma_wr_error(struct ib_cq *cq, struct ib_wc *wc,
11641189
const char *op)
11651190
{
1166-
struct nvme_rdma_queue *queue = cq->cq_context;
1191+
struct nvme_rdma_queue *queue = wc->qp->qp_context;
11671192
struct nvme_rdma_ctrl *ctrl = queue->ctrl;
11681193

11691194
if (ctrl->ctrl.state == NVME_CTRL_LIVE)
@@ -1706,7 +1731,7 @@ static void nvme_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc)
17061731
{
17071732
struct nvme_rdma_qe *qe =
17081733
container_of(wc->wr_cqe, struct nvme_rdma_qe, cqe);
1709-
struct nvme_rdma_queue *queue = cq->cq_context;
1734+
struct nvme_rdma_queue *queue = wc->qp->qp_context;
17101735
struct ib_device *ibdev = queue->device->dev;
17111736
struct nvme_completion *cqe = qe->data;
17121737
const size_t len = sizeof(struct nvme_completion);

0 commit comments

Comments
 (0)