NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
nvmf_doca_io.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
26 #ifndef NVMF_DOCA_IO_H_
27 #define NVMF_DOCA_IO_H_
28 
29 #include <stdint.h>
30 #include <stdbool.h>
31 #include <sys/queue.h>
32 
33 #include <spdk/nvmf_transport.h>
34 
35 #include <doca_error.h>
36 #include <doca_dpa.h>
37 #include <doca_dev.h>
38 #include <doca_buf.h>
39 #include <doca_buf_inventory.h>
40 #include <doca_buf_pool.h>
41 #include <doca_dma.h>
42 #include <doca_devemu_pci.h>
43 #include <doca_comch_msgq.h>
44 #include <doca_comch_producer.h>
45 #include <doca_comch_consumer.h>
46 
47 #define NVMF_DOCA_CQE_SIZE 16
48 #define NVMF_DOCA_SQE_SIZE 64
49 
50 #define DMA_POOL_DATA_BUFFER_SIZE (1UL << 12)
51 
52 struct nvmf_doca_cqe {
54 };
55 
56 struct nvmf_doca_sqe {
58 };
59 
61  struct doca_comch_msgq *msgq;
62  struct doca_comch_producer *producer;
63  struct doca_comch_consumer *consumer;
64  bool is_send;
65 };
66 
68  struct nvmf_doca_dpa_msgq send;
69  struct doca_dpa_completion *producer_comp;
70  struct nvmf_doca_dpa_msgq recv;
71  struct doca_comch_consumer_completion *consumer_comp;
72 };
73 
75  struct doca_buf_inventory *inventory;
76  struct doca_dma *dma;
77  struct doca_mmap *local_queue_mmap;
79  struct doca_dma_task_memcpy **elements;
81  uint32_t num_elements;
82 };
83 
84 struct nvmf_doca_cq {
85  uint32_t cq_id;
86  struct nvmf_doca_queue queue;
87  struct doca_devemu_pci_db *db;
88  struct nvmf_doca_io *io;
89  uint32_t ci;
90  uint32_t pi;
91 };
92 
93 typedef void (*nvmf_doca_cq_post_cqe_cb)(struct nvmf_doca_cq *cq, union doca_data user_data);
94 
97  struct doca_mmap *local_data_mmap;
98  struct doca_buf_pool *local_data_pool;
99  struct doca_mmap *host_data_mmap;
100  struct doca_buf_inventory *host_data_inventory;
101  struct doca_dma *dma;
102 };
103 
104 struct nvmf_doca_io;
105 
106 struct nvmf_doca_request;
107 
108 typedef void (*nvmf_doca_req_cb)(struct nvmf_doca_request *doca_req, void *cb_arg);
109 
111  struct spdk_nvmf_request request;
113  struct spdk_nvme_cpl cq_entry;
114  struct spdk_nvme_cmd command;
115  struct doca_buf *dpu_buffer[NVMF_REQ_MAX_BUFFERS];
116  struct doca_buf *host_buffer[NVMF_REQ_MAX_BUFFERS];
117  struct doca_buf *prp_host_buf;
118  struct doca_buf *prp_dpu_buf;
119  uint32_t num_of_buffers;
120  uint32_t residual_length;
121  uint16_t sqe_idx;
124  void *cb_arg;
126 };
127 
135 };
136 
142 };
143 
144 typedef void (*nvmf_doca_sq_stop_cb)(struct nvmf_doca_sq *sq);
145 
146 struct nvmf_doca_sq {
147  struct spdk_nvmf_qpair spdk_qp;
148  struct nvmf_doca_queue queue;
150  struct doca_devemu_pci_db *db;
152  struct nvmf_doca_io *io;
153  uint32_t pi;
154  uint32_t sq_id;
156  void *ctx;
160  TAILQ_HEAD(, nvmf_doca_request) request_pool;
162  TAILQ_ENTRY(nvmf_doca_sq) pci_dev_admin_link;
163 };
164 
165 typedef void (*nvmf_doca_sq_fetch_sqe_cb)(struct nvmf_doca_sq *sq, struct nvmf_doca_sqe *sqe, uint16_t sqe_idx);
166 typedef void (*nvmf_doca_sq_copy_data_cb)(struct nvmf_doca_sq *sq,
167  struct doca_buf *dst,
168  struct doca_buf *src,
169  union doca_data user_data);
170 
172  struct doca_dpa *dpa;
173  struct doca_dpa_thread *thread;
175 };
176 typedef void (*nvmf_doca_io_stop_cb)(struct nvmf_doca_io *io);
177 
179 
180 struct nvmf_doca_io {
184  struct nvmf_doca_dpa_comch comch;
185  struct nvmf_doca_cq cq;
186  struct doca_devemu_pci_db_completion *db_comp;
187  struct doca_devemu_pci_msix *msix;
193  void *ctx;
195  TAILQ_ENTRY(nvmf_doca_io) pci_dev_admin_link;
196  TAILQ_ENTRY(nvmf_doca_io) pci_dev_pg_link;
197 };
198 
200  struct doca_pe *pe;
201  struct doca_dev *dev;
202  struct doca_devemu_pci_dev *nvme_dev;
203  struct doca_dpa *dpa;
204  uint32_t cq_id;
205  uint16_t cq_depth;
206  struct doca_mmap *host_cq_mmap;
208  bool enable_msix;
209  uint32_t msix_idx;
210  uint32_t max_num_sq;
216 };
217 
218 /*
219  * Create NVMf DOCA IO
220  *
221  * Creates an IO, which can be used to receive DBs on CQ and associated SQs, read SQEs from Host, write CQEs to Host
222  * and raise MSI-X.
223  *
224  * @attr [in]: The IO create attributes
225  * @io [in]: The IO to be initialized
226  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
227  */
229 
230 /*
231  * Destroy NVMf DOCA IO
232  *
233  * @io [in]: The IO to destroy
234  */
235 void nvmf_doca_io_destroy(struct nvmf_doca_io *io);
236 
237 /*
238  * Stop the NVMf DOCA IO canceling all in-flight requests
239  *
240  * Must be done before destroying the IO. Must remove all SQs prior to this operation
241  * This operation is async, once operation completes then nvmf_doca_io::stop_io_cb will be invoked
242  * Once complete then it becomes possible to destroy the IO using nvmf_doca_io_destroy()
243  *
244  * @io [in]: The IO to stop
245  */
246 void nvmf_doca_io_stop(struct nvmf_doca_io *io);
247 
249  struct doca_pe *pe;
250  struct doca_dev *dev;
251  struct doca_devemu_pci_dev *nvme_dev;
252  uint16_t sq_depth;
253  struct doca_mmap *host_sq_mmap;
255  uint32_t sq_id;
256  struct spdk_nvmf_transport *transport;
257  void *ctx;
258 };
259 
260 /*
261  * Add SQ to NVMf DOCA IO
262  *
263  * This operation is async, once operation completes then nvmf_doca_poll_group_add() will be invoked
264  *
265  * @io [in]: The IO to add the SQ to
266  * @attr [in]: The SQ attributes
267  * @sq [in]: The SQ to initialize
268  */
269 void nvmf_doca_io_add_sq(struct nvmf_doca_io *io, const struct nvmf_doca_io_add_sq_attr *attr, struct nvmf_doca_sq *sq);
270 
271 /*
272  * Stop the NVMf DOCA SQ
273  *
274  * This operation is async, once operation completes then nvmf_doca_io::stop_sq_cb will be invoked
275  * Once complete then it becomes possible to remove the SQ using nvmf_doca_io_rm_sq()
276  *
277  * @sq [in]: The SQ to stop
278  */
279 void nvmf_doca_sq_stop(struct nvmf_doca_sq *sq);
280 
281 /*
282  * Remove SQ from NVMf DOCA IO
283  *
284  * Can only be done after nvmf_doca_sq_stop() completes
285  *
286  * @sq [in]: The SQ to remove
287  */
288 void nvmf_doca_io_rm_sq(struct nvmf_doca_sq *sq);
289 
290 /*
291  * Post a CQE to the Host CQ
292  *
293  * This operation is async, once operation completes then nvmf_doca_io::post_cqe_cb will be invoked
294  *
295  * @io [in]: The IO that received the original SQE
296  * @cqe [in]: Contents of the CQE
297  * @user_data [in]: User data to associate with the operation, same data will be available on completion
298  */
299 void nvmf_doca_io_post_cqe(struct nvmf_doca_io *io, const struct nvmf_doca_cqe *cqe, union doca_data user_data);
300 
301 /*
302  * Get buffer containing DPU memory, can be used to copy data between Host and DPU
303  *
304  * Buffer must be freed by caller using doca_buf_dec_refcount()
305  *
306  * @sq [in]: The SQ to be used for the copy operation
307  * @return: Empty buffer to be used for copy operation
308  */
309 struct doca_buf *nvmf_doca_sq_get_dpu_buffer(struct nvmf_doca_sq *sq);
310 
311 /*
312  * Get buffer pointing to Host memory, can be used to copy data between Host and DPU
313  *
314  * Buffer must be freed by caller using doca_buf_dec_refcount()
315  *
316  * @sq [in]: The SQ to be used for the copy operation
317  * @host_io_address [in]: I/O address of Host buffer
318  * @return: Buffer pointing to the given Host I/O address
319  */
320 struct doca_buf *nvmf_doca_sq_get_host_buffer(struct nvmf_doca_sq *sq, uintptr_t host_io_address);
321 
322 /*
323  * Copy data between Host and DPU
324  *
325  * This operation is async, once operation completes then nvmf_doca_io::copy_data_cb will be invoked
326  *
327  * @sq [in]: The SQ used for the copy operation
328  * @dst_buffer [in]: The destination buffer
329  * @src_buffer [in]: The source buffer
330  * @length [in]: The copy operation length
331  * @user_data [in]: User data to associate with the operation, same data will be available on completion of the copy
332  */
333 void nvmf_doca_sq_copy_data(struct nvmf_doca_sq *sq,
334  struct doca_buf *dst_buffer,
335  struct doca_buf *src_buffer,
336  size_t length,
337  union doca_data user_data);
338 
339 /*
340  * Get a request to be used with SPDK QP
341  *
342  * @sq [in]: The NVMf DOCA SQ containing the SPDK QP
343  * @return: The request
344  */
346 
347 /*
348  * Complete the request and free it
349  *
350  * @request [in]: The request
351  */
353 
354 /*
355  * Free the request without completing it
356  *
357  * @request [in]: The request
358  */
360 
361 #endif // NVMF_DOCA_IO_H_
static uint64_t *restrict src
Definition: dpaintrin.h:230
uint64_t doca_dpa_dev_devemu_pci_db_t
DPA handle for emulated PCI device doorbell.
uint64_t doca_dpa_dev_uintptr_t
DPA pointer type definition.
Definition: doca_dpa.h:78
enum doca_error doca_error_t
DOCA API return codes.
void(* nvmf_doca_req_cb)(struct nvmf_doca_request *doca_req, void *cb_arg)
Definition: nvmf_doca_io.h:108
void(* nvmf_doca_sq_stop_cb)(struct nvmf_doca_sq *sq)
Definition: nvmf_doca_io.h:144
struct doca_buf * nvmf_doca_sq_get_dpu_buffer(struct nvmf_doca_sq *sq)
struct doca_buf * nvmf_doca_sq_get_host_buffer(struct nvmf_doca_sq *sq, uintptr_t host_io_address)
void nvmf_doca_request_free(struct nvmf_doca_request *request)
void(* nvmf_doca_sq_fetch_sqe_cb)(struct nvmf_doca_sq *sq, struct nvmf_doca_sqe *sqe, uint16_t sqe_idx)
Definition: nvmf_doca_io.h:165
void nvmf_doca_io_add_sq(struct nvmf_doca_io *io, const struct nvmf_doca_io_add_sq_attr *attr, struct nvmf_doca_sq *sq)
void(* nvmf_doca_io_stop_cb)(struct nvmf_doca_io *io)
Definition: nvmf_doca_io.h:176
void nvmf_doca_request_complete(struct nvmf_doca_request *request)
nvmf_doca_sq_state
Definition: nvmf_doca_io.h:128
@ NVMF_DOCA_SQ_STATE_UNBIND_DB_REQUESTED
Definition: nvmf_doca_io.h:133
@ NVMF_DOCA_SQ_STATE_READY
Definition: nvmf_doca_io.h:132
@ NVMF_DOCA_SQ_STATE_BIND_DB_DONE
Definition: nvmf_doca_io.h:131
@ NVMF_DOCA_SQ_STATE_BIND_DB_REQUESTED
Definition: nvmf_doca_io.h:130
@ NVMF_DOCA_SQ_STATE_UNBIND_DB_DONE
Definition: nvmf_doca_io.h:134
@ NVMF_DOCA_SQ_STATE_INITIAL
Definition: nvmf_doca_io.h:129
void(* nvmf_doca_sq_copy_data_cb)(struct nvmf_doca_sq *sq, struct doca_buf *dst, struct doca_buf *src, union doca_data user_data)
Definition: nvmf_doca_io.h:166
void nvmf_doca_sq_copy_data(struct nvmf_doca_sq *sq, struct doca_buf *dst_buffer, struct doca_buf *src_buffer, size_t length, union doca_data user_data)
void(* nvmf_doca_cq_post_cqe_cb)(struct nvmf_doca_cq *cq, union doca_data user_data)
Definition: nvmf_doca_io.h:93
struct nvmf_doca_request * nvmf_doca_request_get(struct nvmf_doca_sq *sq)
void nvmf_doca_io_destroy(struct nvmf_doca_io *io)
doca_error_t nvmf_doca_io_create(const struct nvmf_doca_io_create_attr *attr, struct nvmf_doca_io *io)
#define NVMF_DOCA_SQE_SIZE
Definition: nvmf_doca_io.h:48
void nvmf_doca_sq_stop(struct nvmf_doca_sq *sq)
nvmf_doca_sq_db_state
Definition: nvmf_doca_io.h:137
@ NVMF_DOCA_SQ_DB_UNBOUND
Definition: nvmf_doca_io.h:138
@ NVMF_DOCA_SQ_DB_BOUND
Definition: nvmf_doca_io.h:140
@ NVMF_DOCA_SQ_DB_UNBIND_REQUESTED
Definition: nvmf_doca_io.h:141
@ NVMF_DOCA_SQ_DB_BIND_REQUESTED
Definition: nvmf_doca_io.h:139
void nvmf_doca_io_stop(struct nvmf_doca_io *io)
#define NVMF_DOCA_CQE_SIZE
Definition: nvmf_doca_io.h:47
void nvmf_doca_io_post_cqe(struct nvmf_doca_io *io, const struct nvmf_doca_cqe *cqe, union doca_data user_data)
void nvmf_doca_io_rm_sq(struct nvmf_doca_sq *sq)
__UINTPTR_TYPE__ uintptr_t
Definition: stdint.h:298
struct doca_devemu_pci_db * db
Definition: nvmf_doca_io.h:87
uint32_t pi
Definition: nvmf_doca_io.h:90
struct nvmf_doca_queue queue
Definition: nvmf_doca_io.h:86
uint32_t cq_id
Definition: nvmf_doca_io.h:85
uint32_t ci
Definition: nvmf_doca_io.h:89
struct nvmf_doca_io * io
Definition: nvmf_doca_io.h:88
uint8_t data[NVMF_DOCA_CQE_SIZE]
Definition: nvmf_doca_io.h:53
struct doca_buf_inventory * host_data_inventory
Definition: nvmf_doca_io.h:100
struct doca_dma * dma
Definition: nvmf_doca_io.h:101
struct doca_mmap * host_data_mmap
Definition: nvmf_doca_io.h:99
struct doca_mmap * local_data_mmap
Definition: nvmf_doca_io.h:97
struct doca_buf_pool * local_data_pool
Definition: nvmf_doca_io.h:98
void * local_data_memory
Definition: nvmf_doca_io.h:96
struct doca_comch_consumer_completion * consumer_comp
Definition: nvmf_doca_io.h:71
struct nvmf_doca_dpa_msgq recv
Definition: nvmf_doca_io.h:70
struct nvmf_doca_dpa_msgq send
Definition: nvmf_doca_io.h:68
struct doca_dpa_completion * producer_comp
Definition: nvmf_doca_io.h:69
struct doca_comch_consumer * consumer
Definition: nvmf_doca_io.h:63
struct doca_comch_msgq * msgq
Definition: nvmf_doca_io.h:61
struct doca_comch_producer * producer
Definition: nvmf_doca_io.h:62
struct doca_dpa * dpa
Definition: nvmf_doca_io.h:172
doca_dpa_dev_uintptr_t arg
Definition: nvmf_doca_io.h:174
struct doca_dpa_thread * thread
Definition: nvmf_doca_io.h:173
struct spdk_nvmf_transport * transport
Definition: nvmf_doca_io.h:256
struct doca_dev * dev
Definition: nvmf_doca_io.h:250
struct doca_devemu_pci_dev * nvme_dev
Definition: nvmf_doca_io.h:251
struct doca_mmap * host_sq_mmap
Definition: nvmf_doca_io.h:253
struct doca_pe * pe
Definition: nvmf_doca_io.h:249
struct doca_mmap * host_cq_mmap
Definition: nvmf_doca_io.h:206
nvmf_doca_sq_copy_data_cb copy_data_cb
Definition: nvmf_doca_io.h:213
struct doca_dpa * dpa
Definition: nvmf_doca_io.h:203
nvmf_doca_cq_post_cqe_cb post_cqe_cb
Definition: nvmf_doca_io.h:211
struct doca_dev * dev
Definition: nvmf_doca_io.h:201
nvmf_doca_sq_fetch_sqe_cb fetch_sqe_cb
Definition: nvmf_doca_io.h:212
nvmf_doca_io_stop_cb stop_io_cb
Definition: nvmf_doca_io.h:215
nvmf_doca_sq_stop_cb stop_sq_cb
Definition: nvmf_doca_io.h:214
struct doca_pe * pe
Definition: nvmf_doca_io.h:200
struct doca_devemu_pci_dev * nvme_dev
Definition: nvmf_doca_io.h:202
struct nvmf_doca_pci_dev_poll_group * poll_group
Definition: nvmf_doca_io.h:181
struct doca_devemu_pci_db_completion * db_comp
Definition: nvmf_doca_io.h:186
TAILQ_ENTRY(nvmf_doca_io) pci_dev_pg_link
struct nvmf_doca_dpa_comch comch
Definition: nvmf_doca_io.h:184
nvmf_doca_io_stop_cb stop_io_cb
Definition: nvmf_doca_io.h:192
TAILQ_HEAD(, nvmf_doca_sq) sq_list
struct nvmf_doca_pci_dev_admin * pci_dev_admin
Definition: nvmf_doca_io.h:182
struct nvmf_doca_dpa_thread dpa_thread
Definition: nvmf_doca_io.h:183
struct doca_devemu_pci_msix * msix
Definition: nvmf_doca_io.h:187
nvmf_doca_cq_post_cqe_cb post_cqe_cb
Definition: nvmf_doca_io.h:188
struct nvmf_doca_cq cq
Definition: nvmf_doca_io.h:185
nvmf_doca_sq_stop_cb stop_sq_cb
Definition: nvmf_doca_io.h:191
nvmf_doca_sq_copy_data_cb copy_data_cb
Definition: nvmf_doca_io.h:190
TAILQ_ENTRY(nvmf_doca_io) pci_dev_admin_link
nvmf_doca_sq_fetch_sqe_cb fetch_sqe_cb
Definition: nvmf_doca_io.h:189
struct doca_mmap * local_queue_mmap
Definition: nvmf_doca_io.h:77
struct doca_buf_inventory * inventory
Definition: nvmf_doca_io.h:75
uint32_t num_elements
Definition: nvmf_doca_io.h:81
struct doca_dma * dma
Definition: nvmf_doca_io.h:76
struct doca_dma_task_memcpy ** elements
Definition: nvmf_doca_io.h:79
void * local_queue_address
Definition: nvmf_doca_io.h:78
struct spdk_nvme_cpl cq_entry
Definition: nvmf_doca_io.h:113
struct doca_buf * prp_dpu_buf
Definition: nvmf_doca_io.h:118
struct doca_buf * dpu_buffer[NVMF_REQ_MAX_BUFFERS]
Definition: nvmf_doca_io.h:115
uint32_t num_of_buffers
Definition: nvmf_doca_io.h:119
TAILQ_ENTRY(nvmf_doca_request) link
struct spdk_nvmf_request request
Definition: nvmf_doca_io.h:111
uint32_t residual_length
Definition: nvmf_doca_io.h:120
nvmf_doca_req_cb doca_cb
Definition: nvmf_doca_io.h:123
struct doca_buf * host_buffer[NVMF_REQ_MAX_BUFFERS]
Definition: nvmf_doca_io.h:116
struct nvmf_doca_sq * doca_sq
Definition: nvmf_doca_io.h:112
struct doca_buf * prp_host_buf
Definition: nvmf_doca_io.h:117
struct spdk_nvme_cmd command
Definition: nvmf_doca_io.h:114
doca_error_t result
Definition: nvmf_doca_io.h:158
enum nvmf_doca_sq_db_state db_state
Definition: nvmf_doca_io.h:157
struct nvmf_doca_request * request_pool_memory
Definition: nvmf_doca_io.h:159
TAILQ_ENTRY(nvmf_doca_sq) pci_dev_admin_link
TAILQ_ENTRY(nvmf_doca_sq) link
TAILQ_HEAD(, nvmf_doca_request) request_pool
uint32_t sq_id
Definition: nvmf_doca_io.h:154
doca_dpa_dev_devemu_pci_db_t db_handle
Definition: nvmf_doca_io.h:151
struct nvmf_doca_dma_pool dma_pool
Definition: nvmf_doca_io.h:149
struct nvmf_doca_io * io
Definition: nvmf_doca_io.h:152
struct doca_devemu_pci_db * db
Definition: nvmf_doca_io.h:150
struct spdk_nvmf_qpair spdk_qp
Definition: nvmf_doca_io.h:147
uint32_t pi
Definition: nvmf_doca_io.h:153
struct nvmf_doca_queue queue
Definition: nvmf_doca_io.h:148
enum nvmf_doca_sq_state state
Definition: nvmf_doca_io.h:155
uint8_t data[NVMF_DOCA_SQE_SIZE]
Definition: nvmf_doca_io.h:57
Convenience type for representing opaque data.
Definition: doca_types.h:56