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