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 succes, 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 succes, 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 succes, 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 succes, 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