Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2021 Intel Corporation. All rights reserved.
3 : : * Copyright (c) 2020, 2021 Mellanox Technologies LTD. All rights reserved.
4 : : * Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5 : : */
6 : :
7 : : #include <rdma/rdma_cma.h>
8 : :
9 : : #include "spdk/log.h"
10 : : #include "spdk/string.h"
11 : : #include "spdk/likely.h"
12 : :
13 : : #include "spdk_internal/rdma_provider.h"
14 : :
15 : : struct spdk_rdma_provider_srq *
16 : 264 : spdk_rdma_provider_srq_create(struct spdk_rdma_provider_srq_init_attr *init_attr)
17 : : {
18 [ - + # # ]: 264 : assert(init_attr);
19 [ - + # # : 264 : assert(init_attr->pd);
# # # # ]
20 : :
21 : 264 : struct spdk_rdma_provider_srq *rdma_srq = calloc(1, sizeof(*rdma_srq));
22 : :
23 [ - + ]: 264 : if (!rdma_srq) {
24 : 0 : SPDK_ERRLOG("Can't allocate memory for SRQ handle\n");
25 : 0 : return NULL;
26 : : }
27 : :
28 [ + - # # : 264 : if (init_attr->stats) {
# # ]
29 [ # # # # : 264 : rdma_srq->stats = init_attr->stats;
# # # # ]
30 [ # # # # ]: 264 : rdma_srq->shared_stats = true;
31 : 0 : } else {
32 [ # # # # ]: 0 : rdma_srq->stats = calloc(1, sizeof(*rdma_srq->stats));
33 [ # # # # : 0 : if (!rdma_srq->stats) {
# # ]
34 : 0 : SPDK_ERRLOG("SRQ statistics memory allocation failed");
35 : 0 : free(rdma_srq);
36 : 0 : return NULL;
37 : : }
38 : : }
39 : :
40 [ # # # # : 264 : rdma_srq->srq = ibv_create_srq(init_attr->pd, &init_attr->srq_init_attr);
# # # # #
# ]
41 [ - + # # : 264 : if (!rdma_srq->srq) {
# # ]
42 [ # # # # : 0 : if (!init_attr->stats) {
# # ]
43 [ # # # # ]: 0 : free(rdma_srq->stats);
44 : 0 : }
45 [ # # # # ]: 0 : SPDK_ERRLOG("Unable to create SRQ, errno %d (%s)\n", errno, spdk_strerror(errno));
46 : 0 : free(rdma_srq);
47 : 0 : return NULL;
48 : : }
49 : :
50 : 264 : return rdma_srq;
51 : 0 : }
52 : :
53 : : int
54 : 264 : spdk_rdma_provider_srq_destroy(struct spdk_rdma_provider_srq *rdma_srq)
55 : : {
56 : : int rc;
57 : :
58 [ - + ]: 264 : if (!rdma_srq) {
59 : 0 : return 0;
60 : : }
61 : :
62 [ - + # # : 264 : assert(rdma_srq->srq);
# # # # ]
63 : :
64 [ - + # # : 264 : if (rdma_srq->recv_wrs.first != NULL) {
# # # # ]
65 : 0 : SPDK_WARNLOG("Destroying RDMA SRQ with queued recv WRs\n");
66 : 0 : }
67 : :
68 [ # # # # ]: 264 : rc = ibv_destroy_srq(rdma_srq->srq);
69 [ - + ]: 264 : if (rc) {
70 : 0 : SPDK_ERRLOG("SRQ destroy failed with %d\n", rc);
71 : 0 : }
72 : :
73 [ - + - + : 264 : if (!rdma_srq->shared_stats) {
# # # # ]
74 [ # # # # ]: 0 : free(rdma_srq->stats);
75 : 0 : }
76 : :
77 : 264 : free(rdma_srq);
78 : :
79 : 264 : return rc;
80 : 0 : }
81 : :
82 : : static inline bool
83 : 11825422 : rdma_queue_recv_wrs(struct spdk_rdma_provider_recv_wr_list *recv_wrs, struct ibv_recv_wr *first,
84 : : struct spdk_rdma_provider_wr_stats *recv_stats)
85 : : {
86 : : struct ibv_recv_wr *last;
87 : :
88 [ # # ]: 11825422 : recv_stats->num_submitted_wrs++;
89 : 11825422 : last = first;
90 [ - + # # : 11825422 : while (last->next != NULL) {
# # ]
91 [ # # # # ]: 0 : last = last->next;
92 [ # # ]: 0 : recv_stats->num_submitted_wrs++;
93 : : }
94 : :
95 [ + + # # : 11825422 : if (recv_wrs->first == NULL) {
# # ]
96 [ # # # # ]: 1410907 : recv_wrs->first = first;
97 [ # # # # ]: 1410907 : recv_wrs->last = last;
98 : 1410907 : return true;
99 : : } else {
100 [ # # # # : 10414515 : recv_wrs->last->next = first;
# # # # ]
101 [ # # # # ]: 10414515 : recv_wrs->last = last;
102 : 10414515 : return false;
103 : : }
104 : 0 : }
105 : :
106 : : bool
107 : 6148960 : spdk_rdma_provider_srq_queue_recv_wrs(struct spdk_rdma_provider_srq *rdma_srq,
108 : : struct ibv_recv_wr *first)
109 : : {
110 [ - + # # ]: 6148960 : assert(rdma_srq);
111 [ - + # # ]: 6148960 : assert(first);
112 : :
113 [ # # # # : 6148960 : return rdma_queue_recv_wrs(&rdma_srq->recv_wrs, first, rdma_srq->stats);
# # ]
114 : : }
115 : :
116 : : int
117 : 435241249 : spdk_rdma_provider_srq_flush_recv_wrs(struct spdk_rdma_provider_srq *rdma_srq,
118 : : struct ibv_recv_wr **bad_wr)
119 : : {
120 : : int rc;
121 : :
122 [ + + # # : 435241249 : if (spdk_unlikely(rdma_srq->recv_wrs.first == NULL)) {
# # # # ]
123 : 434617935 : return 0;
124 : : }
125 : :
126 [ # # # # : 623314 : rc = ibv_post_srq_recv(rdma_srq->srq, rdma_srq->recv_wrs.first, bad_wr);
# # # # #
# ]
127 : :
128 [ # # # # : 623314 : rdma_srq->recv_wrs.first = NULL;
# # ]
129 [ # # # # : 623314 : rdma_srq->stats->doorbell_updates++;
# # ]
130 : :
131 : 623314 : return rc;
132 : 0 : }
133 : :
134 : : bool
135 : 5676462 : spdk_rdma_provider_qp_queue_recv_wrs(struct spdk_rdma_provider_qp *spdk_rdma_qp,
136 : : struct ibv_recv_wr *first)
137 : : {
138 [ - + # # ]: 5676462 : assert(spdk_rdma_qp);
139 [ - + # # ]: 5676462 : assert(first);
140 : :
141 [ # # # # : 5676462 : return rdma_queue_recv_wrs(&spdk_rdma_qp->recv_wrs, first, &spdk_rdma_qp->stats->recv);
# # # # ]
142 : : }
143 : :
144 : : int
145 : 83186696 : spdk_rdma_provider_qp_flush_recv_wrs(struct spdk_rdma_provider_qp *spdk_rdma_qp,
146 : : struct ibv_recv_wr **bad_wr)
147 : : {
148 : : int rc;
149 : :
150 [ + + # # : 83186696 : if (spdk_unlikely(spdk_rdma_qp->recv_wrs.first == NULL)) {
# # # # ]
151 : 82399112 : return 0;
152 : : }
153 : :
154 [ # # # # : 787584 : rc = ibv_post_recv(spdk_rdma_qp->qp, spdk_rdma_qp->recv_wrs.first, bad_wr);
# # # # #
# ]
155 : :
156 [ # # # # : 787584 : spdk_rdma_qp->recv_wrs.first = NULL;
# # ]
157 [ # # # # : 787584 : spdk_rdma_qp->stats->recv.doorbell_updates++;
# # # # ]
158 : :
159 : 787584 : return rc;
160 : 0 : }
|