NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
doca_utils.hpp
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 APPLICATIONS_STORAGE_STORAGE_COMMON_DOCA_UTILS_HPP_
27 #define APPLICATIONS_STORAGE_STORAGE_COMMON_DOCA_UTILS_HPP_
28 
29 #include <cstddef>
30 #include <chrono>
31 #include <string>
32 #include <vector>
33 
34 #include <doca_argp.h>
35 #include <doca_buf.h>
36 #include <doca_buf_inventory.h>
37 #include <doca_comch.h>
38 #include <doca_comch_consumer.h>
39 #include <doca_comch_producer.h>
40 #include <doca_ctx.h>
41 #include <doca_dev.h>
42 #include <doca_erasure_coding.h>
43 #include <doca_mmap.h>
44 #include <doca_pe.h>
45 #include <doca_rdma.h>
46 
47 namespace storage {
48 
49 /*
50  * Helper to keep a RDMA connection and its associated context together as pairs
51  */
53  doca_rdma *rdma = nullptr; /* RDMA context */
54  doca_rdma_connection *conn = nullptr; /* RDMA connection */
55 };
56 
57 /*
58  * Find and open a device with the given identifier. May match any one of:
59  * - InfiniBand device name(eg: mlx5_0)
60  * - Network interface name(eg: ens1f0np0)
61  * - PCI address(eg: 03:00.0)
62  *
63  * @throws std::runtime_error: If no device matches the given name / identifier OR if opening the device failed
64  *
65  * @identifier [in]: Identifier to use when selecting a device to use
66  * @return: The found and opened device
67  */
68 doca_dev *open_device(std::string const &identifier);
69 
70 /*
71  * Find and open a device representor with the given identifier. May match any one of:
72  * - PCI address(eg: 03:00.0)
73  *
74  * @throws std::runtime_error: If no device representor matches the given identifier OR if opening the device
75  * representor failed
76  *
77  * @dev [in]: Device to be represented. Must point to a valid open device
78  * @identifier [in]: Identifier to use when selecting a device representor to use
79  * @return: The found and opened device representor
80  */
81 doca_dev_rep *open_representor(doca_dev *dev, std::string const &identifier);
82 
83 /*
84  * Create, initialize and start a mmap to make the provided memory available to be used in doca_buf objects using the
85  * provided device
86  *
87  * @throws std::runtime_error: If allocation, initialization or starting of the mmap fails
88  *
89  * @dev [in]: Device which the memory will be used with
90  * @memory_region [in]: Start of the memory region to use
91  * @memory_region_size[in]: Size (in bytes) of the memory region
92  * @permissions [in]: Bit masked set of permissions to apply to the mmap. See enum doca_access_flag
93  * @return: The newly created, initialized and started mmap
94  */
95 doca_mmap *make_mmap(doca_dev *dev, char *memory_region, size_t memory_region_size, uint32_t permissions);
96 
97 /*
98  * Create, initialize and start a mmap from a remote export. See doca_mmap_export_pci and doca_mmap_export_rdma
99  *
100  * @throws std::runtime_error :If allocation, initialization or starting of the mmap fails
101  *
102  * @dev [in]: Device which the memory will be used with
103  * @mmap_export_blob [in]: The remote export blob buffer
104  * @mmap_export_blob_size[in]: Size (in bytes) of the remote export blob buffer
105  * @return: The newly created, initialized and started mmap
106  */
107 doca_mmap *make_mmap(doca_dev *dev, void const *mmap_export_blob, size_t mmap_export_blob_size);
108 
109 /*
110  * Create, initialize and start a buffer inventory
111  *
112  * @throws std::runtime_error: If allocation, initialization or starting of the inventory fails
113  *
114  * @num_elements [in]: Number of doca_bufs this inventory can provide to the user
115  * @return: The newly created, initialized and started inventory
116  */
117 doca_buf_inventory *make_buf_inventory(size_t num_elements);
118 
119 /*
120  * Create, initialize and start a comch consumer. Ready to connect to a remote producer
121  *
122  * @throws std::runtime_error: If allocation, initialization or starting of the consumer fails
123  *
124  * @conn [in]: Established comch control path connection to use
125  * @mmap [in]: Mmap from which the buffers submitted with receive tasks will be allocated from
126  * @pe [in]: The progress engine that will be used to schedule work execution for the consumer
127  * @task_pool_size [in]: Maximum number of consumer receive tasks that can be allocated
128  * @ctx_user_data [in]: Data that will be used as the context user data for each invocation of this consumers task
129  * callbacks
130  * @task_cb [in]: The callback to be invoked when this consumer has received a message
131  * @error_cb [in]: The callback to be invoked when a doca_comch_consumer_task_post_recv task fails
132  * @return: The newly created, initialized and started consumer
133  */
134 doca_comch_consumer *make_comch_consumer(doca_comch_connection *conn,
135  doca_mmap *mmap,
136  doca_pe *pe,
137  uint32_t task_pool_size,
138  doca_data ctx_user_data,
141 
142 /*
143  * Create, initialize and start a comch producer. Ready to connect to a remote consumer
144  *
145  * @throws std::runtime_error: If allocation, initialization or starting of the producer fails
146  *
147  * @conn [in]: Established comch control path connection to use
148  * @pe [in]: The progress engine that will be used to schedule work execution for the producer
149  * @task_pool_size [in]: Maximum number of producer send tasks that can be allocated
150  * @ctx_user_data [in]: Data that will be used as the context user data for each invocation of this producers task
151  * callbacks
152  * @task_cb [in]: The callback to be invoked when this producer has sent a message
153  * @error_cb [in]: The callback to be invoked when a doca_comch_producer_task_send task fails
154  * @return: The newly created, initialized and started producer
155  */
156 doca_comch_producer *make_comch_producer(doca_comch_connection *conn,
157  doca_pe *pe,
158  uint32_t task_pool_size,
159  doca_data ctx_user_data,
162 
163 /*
164  * Create and partially initialize an RDMA context. The user will still need to:
165  * - Configure task pools for the RDMA task types they want to use
166  * - Start the context
167  * - Export the connection details and provide these to the remote side
168  * - Retrieve the remote sides RDMA connection details
169  * - Connect using the provided connection details
170  * - Progress the progress engine until the RDMA context is ready to send / receive tasks
171  *
172  * @throws std::runtime_error: If allocation or partially initialization of the RDMA context fails
173  *
174  * @dev [in]: Device to use
175  * @pe [in]: The progress engine that will be used to schedule work execution for the RDMA context
176  * @ctx_user_data [in]: Data that will be used as the context user data for each invocation of this producers task
177  * callbacks
178  * @permissions [in]: Bitwise combination of RDMA access flags - see enum doca_access_flag
179  * @return: The newly created and partially initialized RDMA context
180  */
181 doca_rdma *make_rdma_context(doca_dev *dev, doca_pe *pe, doca_data ctx_user_data, uint32_t permissions);
182 
183 /*
184  * Check if a context is running / started
185  *
186  * @ctx [in]: Context to query
187  * @return: true if the context is running, false otherwise
188  */
189 bool is_ctx_running(doca_ctx *ctx) noexcept;
190 
191 /*
192  * Stop the context
193  *
194  * @ctx [in]: The context to stop
195  * @pe [in]: The progress engine associated with the context
196  * @return: DOCA_SUCCESS or error code upon failure
197  */
198 doca_error_t stop_context(doca_ctx *ctx, doca_pe *pe) noexcept;
199 
200 /*
201  * Stop the context and release tasks
202  *
203  * @ctx [in]: The context to stop
204  * @pe [in]: The progress engine associated with the context
205  * @ctx_tasks [in]: The set of tasks that are owned by the given context so they can be freed after they are flushed by
206  * the context during the stop process
207  * @return: DOCA_SUCCESS or error code upon failure
208  */
209 doca_error_t stop_context(doca_ctx *ctx, doca_pe *pe, std::vector<doca_task *> &ctx_tasks) noexcept;
210 
211 /*
212  * Strongly typed boolean to make usage clearer
213  */
215  bool is_required; /* true if the value is mandatory, false if it is optional */
216 };
217 
218 /*
219  * Strongly typed boolean to make usage clearer
220  */
222  bool support_multiple_values; /* true if a value can be specified multiple times, false when it can be specified
223  * at most once
224  */
225 };
226 
227 static value_requirement constexpr required_value{true}; /* helper alias */
228 static value_requirement constexpr optional_value{false}; /* helper alias */
229 
230 static value_multiplicity constexpr single_value{false}; /* helper alias */
231 static value_multiplicity constexpr multiple_values{true}; /* helper alias */
232 
233 /*
234  * Register a parameter with doca_argp
235  *
236  * @throws std::runtime_error: If something goes wrong
237  *
238  * @type [in]: value category
239  * @short_name [in]: The short name for the value, or nullptr if not supported
240  * @long_name [in]: The long name for the value, or nullptr if not supported
241  * @description [in]: Description of the value
242  * @requirement [in]: Is the value required
243  * @multiplicity [in]: Value multiplicity
244  * @callback [in]: Parameter value handler
245  */
247  char const *short_name,
248  char const *long_name,
249  char const *description,
250  value_requirement requirement,
251  value_multiplicity multiplicity,
252  doca_argp_param_cb_t callback);
253 
254 /*
255  * Helper to get a pointer to the contents of a doca buf
256  *
257  * @buf [in]: Pointer to doca_buf whose underlying bytes are desired
258  * @return: Pointer to buffer bytes
259  */
260 inline char *get_buffer_bytes(doca_buf *buf) noexcept
261 {
262  void *data;
263  static_cast<void>(doca_buf_get_data(buf, &data));
264  return static_cast<char *>(data);
265 }
266 
267 /*
268  * Helper to get a pointer to the contents of a doca buf
269  *
270  * @buf [in]: Pointer to doca_buf whose underlying bytes are desired
271  * @return: Pointer to buffer bytes
272  */
273 inline char const *get_buffer_bytes(doca_buf const *buf) noexcept
274 {
275  void *data;
276  static_cast<void>(doca_buf_get_data(const_cast<doca_buf *>(buf), &data));
277  return static_cast<char const *>(data);
278 }
279 
280 /*
281  * Create a logger backend. This only needs called one per application
282  */
283 void create_doca_logger_backend(void) noexcept;
284 
285 /*
286  * String to enum conversion
287  *
288  * @matrix_type [in]: String representation
289  * @return enum or throw if unknown
290  */
291 doca_ec_matrix_type matrix_type_from_string(std::string const &matrix_type);
292 
293 } /* namespace storage */
294 
295 #endif /* APPLICATIONS_STORAGE_STORAGE_COMMON_DOCA_UTILS_HPP_ */
doca_dpa_dev_mmap_t mmap
static struct doca_pe * pe
doca_argp_type
Flag input type.
Definition: doca_argp.h:54
doca_error_t(* doca_argp_param_cb_t)(void *, void *)
Flag callback function type.
Definition: doca_argp.h:37
DOCA_STABLE doca_error_t doca_buf_get_data(const struct doca_buf *buf, void **data)
Get the buffer's data.
void(* doca_comch_consumer_task_post_recv_completion_cb_t)(struct doca_comch_consumer_task_post_recv *task, union doca_data task_user_data, union doca_data ctx_user_data)
void(* doca_comch_producer_task_send_completion_cb_t)(struct doca_comch_producer_task_send *task, union doca_data task_user_data, union doca_data ctx_user_data)
doca_ec_matrix_type
Types of coding matrix used for erasure codes.
enum doca_error doca_error_t
DOCA API return codes.
type description
doca_mmap * make_mmap(doca_dev *dev, char *memory_region, size_t memory_region_size, uint32_t permissions)
Definition: doca_utils.cpp:146
static constexpr value_requirement optional_value
Definition: doca_utils.hpp:228
doca_buf_inventory * make_buf_inventory(size_t num_elements)
Definition: doca_utils.cpp:205
void create_doca_logger_backend(void) noexcept
Definition: doca_utils.cpp:471
doca_comch_producer * make_comch_producer(doca_comch_connection *conn, doca_pe *pe, uint32_t task_pool_size, doca_data callback_user_data, doca_comch_producer_task_send_completion_cb_t task_cb, doca_comch_producer_task_send_completion_cb_t error_cb)
Definition: doca_utils.cpp:279
doca_rdma * make_rdma_context(doca_dev *dev, doca_pe *pe, doca_data ctx_user_data, uint32_t permissions)
Definition: doca_utils.cpp:331
static constexpr value_multiplicity multiple_values
Definition: doca_utils.hpp:231
void register_cli_argument(doca_argp_type type, char const *short_name, char const *long_name, char const *description, value_requirement requirement, value_multiplicity multiplicity, doca_argp_param_cb_t callback)
Definition: doca_utils.cpp:413
doca_ec_matrix_type matrix_type_from_string(std::string const &matrix_type)
Definition: doca_utils.cpp:503
char * get_buffer_bytes(doca_buf *buf) noexcept
Definition: doca_utils.hpp:260
doca_dev_rep * open_representor(doca_dev *dev, std::string const &identifier)
Definition: doca_utils.cpp:104
static constexpr value_multiplicity single_value
Definition: doca_utils.hpp:230
doca_comch_consumer * make_comch_consumer(doca_comch_connection *conn, doca_mmap *mmap, doca_pe *pe, uint32_t task_pool_size, doca_data callback_user_data, doca_comch_consumer_task_post_recv_completion_cb_t task_cb, doca_comch_consumer_task_post_recv_completion_cb_t error_cb)
Definition: doca_utils.cpp:224
bool is_ctx_running(doca_ctx *ctx) noexcept
Definition: doca_utils.cpp:362
static constexpr value_requirement required_value
Definition: doca_utils.hpp:227
doca_error_t stop_context(doca_ctx *ctx, doca_pe *pe) noexcept
Definition: doca_utils.cpp:369
doca_dev * open_device(std::string const &identifier)
Definition: doca_utils.cpp:43
uint8_t type
Definition: packets.h:0
doca_rdma_connection * conn
Definition: doca_utils.hpp:54
Convenience type for representing opaque data.
Definition: doca_types.h:56
struct upf_accel_ctx * ctx