xref: /spdk/include/spdk_internal/rdma_provider.h (revision c6c1234de9e0015e670dd0b51bf6ce39ee0e07bd)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) Mellanox Technologies LTD. All rights reserved.
3  *   Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4  */
5 
6 #ifndef SPDK_RDMA_H
7 #define SPDK_RDMA_H
8 
9 #include <infiniband/verbs.h>
10 #include <rdma/rdma_cma.h>
11 #include <rdma/rdma_verbs.h>
12 
13 /* rxe driver vendor_id has been changed from 0 to 0XFFFFFF in 0184afd15a141d7ce24c32c0d86a1e3ba6bc0eb3 */
14 #define SPDK_RDMA_RXE_VENDOR_ID_OLD 0
15 #define SPDK_RDMA_RXE_VENDOR_ID_NEW 0XFFFFFF
16 
17 struct spdk_rdma_provider_wr_stats {
18 	/* Total number of submitted requests */
19 	uint64_t num_submitted_wrs;
20 	/* Total number of doorbell updates */
21 	uint64_t doorbell_updates;
22 };
23 
24 struct spdk_rdma_provider_qp_stats {
25 	struct spdk_rdma_provider_wr_stats send;
26 	struct spdk_rdma_provider_wr_stats recv;
27 };
28 
29 struct spdk_rdma_provider_qp_init_attr {
30 	void		       *qp_context;
31 	struct ibv_cq	       *send_cq;
32 	struct ibv_cq	       *recv_cq;
33 	struct ibv_srq	       *srq;
34 	struct ibv_qp_cap	cap;
35 	struct ibv_pd	       *pd;
36 	struct spdk_rdma_provider_qp_stats *stats;
37 };
38 
39 struct spdk_rdma_provider_send_wr_list {
40 	struct ibv_send_wr	*first;
41 	struct ibv_send_wr	*last;
42 };
43 
44 struct spdk_rdma_provider_recv_wr_list {
45 	struct ibv_recv_wr	*first;
46 	struct ibv_recv_wr	*last;
47 };
48 
49 struct spdk_rdma_provider_qp {
50 	struct ibv_qp *qp;
51 	struct rdma_cm_id *cm_id;
52 	struct spdk_rdma_provider_send_wr_list send_wrs;
53 	struct spdk_rdma_provider_recv_wr_list recv_wrs;
54 	struct spdk_rdma_provider_qp_stats *stats;
55 	bool shared_stats;
56 };
57 
58 struct spdk_rdma_provider_srq_init_attr {
59 	struct ibv_pd *pd;
60 	struct spdk_rdma_provider_wr_stats *stats;
61 	struct ibv_srq_init_attr srq_init_attr;
62 };
63 
64 struct spdk_rdma_provider_srq {
65 	struct ibv_srq *srq;
66 	struct spdk_rdma_provider_recv_wr_list recv_wrs;
67 	struct spdk_rdma_provider_wr_stats *stats;
68 	bool shared_stats;
69 };
70 
71 /**
72  * Create RDMA SRQ
73  *
74  * \param init_attr Pointer to SRQ init attr
75  * \return pointer to srq on success or NULL on failure. errno is updated in failure case.
76  */
77 struct spdk_rdma_provider_srq *spdk_rdma_provider_srq_create(
78 	struct spdk_rdma_provider_srq_init_attr *init_attr);
79 
80 /**
81  * Destroy RDMA SRQ
82  *
83  * \param rdma_srq Pointer to SRQ
84  * \return 0 on success, errno on failure
85  */
86 int spdk_rdma_provider_srq_destroy(struct spdk_rdma_provider_srq *rdma_srq);
87 
88 /**
89  * Append the given recv wr structure to the SRQ's outstanding recv list.
90  * This function accepts either a single Work Request or the first WR in a linked list.
91  *
92  * \param rdma_srq Pointer to SRQ
93  * \param first pointer to the first Work Request
94  * \return true if there were no outstanding WRs before, false otherwise
95  */
96 bool spdk_rdma_provider_srq_queue_recv_wrs(struct spdk_rdma_provider_srq *rdma_srq,
97 		struct ibv_recv_wr *first);
98 
99 /**
100  * Submit all queued receive Work Request
101  *
102  * \param rdma_srq Pointer to SRQ
103  * \param bad_wr Stores a pointer to the first failed WR if this function return nonzero value
104  * \return 0 on success, errno on failure
105  */
106 int spdk_rdma_provider_srq_flush_recv_wrs(struct spdk_rdma_provider_srq *rdma_srq,
107 		struct ibv_recv_wr **bad_wr);
108 
109 /**
110  * Create RDMA provider specific qpair
111  *
112  * \param cm_id Pointer to RDMA_CM cm_id
113  * \param qp_attr Pointer to qpair init attributes
114  * \return Pointer to a newly created qpair on success or NULL on failure
115  */
116 struct spdk_rdma_provider_qp *spdk_rdma_provider_qp_create(struct rdma_cm_id *cm_id,
117 		struct spdk_rdma_provider_qp_init_attr *qp_attr);
118 
119 /**
120  * Accept a connection request. Called by the passive side (NVMEoF target)
121  *
122  * \param spdk_rdma_qp Pointer to SPDK RDMA qpair
123  * \param conn_param Optional information needed to establish the connection
124  * \return 0 on success, errno on failure
125  */
126 int spdk_rdma_provider_qp_accept(struct spdk_rdma_provider_qp *spdk_rdma_qp,
127 				 struct rdma_conn_param *conn_param);
128 
129 /**
130  * Complete the connection process, must be called by the active
131  * side (NVMEoF initiator) upon receipt RDMA_CM_EVENT_CONNECT_RESPONSE
132  *
133  * \param spdk_rdma_qp Pointer to SPDK RDMA qpair
134  * \return 0 on success, errno on failure
135  */
136 int spdk_rdma_provider_qp_complete_connect(struct spdk_rdma_provider_qp *spdk_rdma_qp);
137 
138 /**
139  * Destroy RDMA provider specific qpair
140  *
141  * \param spdk_rdma_qp Pointer to SPDK RDMA qpair to be destroyed
142  */
143 void spdk_rdma_provider_qp_destroy(struct spdk_rdma_provider_qp *spdk_rdma_qp);
144 
145 /**
146  * Disconnect a connection and transition associated qpair to error state.
147  * Generates RDMA_CM_EVENT_DISCONNECTED on both connection sides
148  *
149  * \param spdk_rdma_qp Pointer to qpair to be disconnected
150  */
151 int spdk_rdma_provider_qp_disconnect(struct spdk_rdma_provider_qp *spdk_rdma_qp);
152 
153 /**
154  * Append the given send wr structure to the qpair's outstanding sends list.
155  * This function accepts either a single Work Request or the first WR in a linked list.
156  *
157  * \param spdk_rdma_qp Pointer to SPDK RDMA qpair
158  * \param first Pointer to the first Work Request
159  * \return true if there were no outstanding WRs before, false otherwise
160  */
161 bool spdk_rdma_provider_qp_queue_send_wrs(struct spdk_rdma_provider_qp *spdk_rdma_qp,
162 		struct ibv_send_wr *first);
163 
164 /**
165  * Submit all queued send Work Request
166  *
167  * \param spdk_rdma_qp Pointer to SPDK RDMA qpair
168  * \param bad_wr Stores a pointer to the first failed WR if this function return nonzero value
169  * \return 0 on success, errno on failure
170  */
171 int spdk_rdma_provider_qp_flush_send_wrs(struct spdk_rdma_provider_qp *spdk_rdma_qp,
172 		struct ibv_send_wr **bad_wr);
173 
174 /**
175  * Append the given recv wr structure to the qpair's outstanding recv list.
176  * This function accepts either a single Work Request or the first WR in a linked list.
177  *
178  * \param spdk_rdma_qp Pointer to SPDK RDMA qpair
179  * \param first Pointer to the first Work Request
180  * \return true if there were no outstanding WRs before, false otherwise
181  */
182 bool spdk_rdma_provider_qp_queue_recv_wrs(struct spdk_rdma_provider_qp *spdk_rdma_qp,
183 		struct ibv_recv_wr *first);
184 
185 /**
186  * Submit all queued recv Work Request
187  * \param spdk_rdma_qp Pointer to SPDK RDMA qpair
188  * \param bad_wr Stores a pointer to the first failed WR if this function return nonzero value
189  * \return 0 on success, errno on failure
190  */
191 int spdk_rdma_provider_qp_flush_recv_wrs(struct spdk_rdma_provider_qp *spdk_rdma_qp,
192 		struct ibv_recv_wr **bad_wr);
193 
194 #endif /* SPDK_RDMA_H */
195