NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
control_message.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2025 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_CONTROL_MESSAGE_HPP_
27 #define APPLICATIONS_STORAGE_STORAGE_COMMON_CONTROL_MESSAGE_HPP_
28 
29 #include <cstdint>
30 #include <memory>
31 #include <vector>
32 #include <string>
33 
34 #include <doca_error.h>
35 
36 namespace storage::control {
37 
39  io_data, /* Connection to transfer data to or from the storage */
40  io_control, /* Connection to exchange io commands and io responses */
41 };
42 
43 struct message_id {
44  uint32_t value;
45 };
46 
47 inline bool operator==(message_id const &lhs, message_id const &rhs)
48 {
49  return lhs.value == rhs.value;
50 }
51 
53  uint32_t value;
54 };
55 
56 enum class message_type : uint32_t {
57  error_response = 0,
70 };
71 
73  uint32_t wire_size;
74 };
75 
76 struct message {
77  struct payload {
78  virtual ~payload() = default;
79  };
80 
81  // Type of message, so that the type of payload (if any) is known
83  // Message ID uniquely identifies a pair of request / response messages
85  // Correlation id allows to track "sets" of request / response pairs as related to each other
87  std::unique_ptr<storage::control::message::payload> payload;
88 };
89 
90 /*
91  * Error details
92  */
95  std::string message; /* A message to give the caller some context / understanding of the error */
96 
97  ~error_response_payload() override = default;
99  error_response_payload(doca_error_t error_code_, std::string message_)
100  : error_code{error_code_},
101  message{std::move(message_)}
102  {
103  }
106  error_response_payload &operator=(error_response_payload const &) = default;
107  error_response_payload &operator=(error_response_payload &&) noexcept = default;
108 };
109 
110 /*
111  * Storage query
112  */
113 struct storage_details_payload : public storage::control::message::payload {
114  uint64_t total_size; /* Total size of the storage */
115  uint32_t block_size; /* Block size used by the storage */
116 
117  ~storage_details_payload() override = default;
119  storage_details_payload(uint64_t total_size_, uint32_t block_size_)
120  : total_size{total_size_},
121  block_size{block_size_}
122  {
123  }
126  storage_details_payload &operator=(storage_details_payload const &) = default;
127  storage_details_payload &operator=(storage_details_payload &&) noexcept = default;
128 };
129 
130 /*
131  * Storage initialisation
132  */
133 struct init_storage_payload : public storage::control::message::payload {
134  uint32_t task_count; /* Number of tasks to use */
135  uint32_t batch_size; /* Batch size to use */
136  uint32_t core_count; /* Number of cores to use */
137  std::vector<uint8_t> mmap_export_blob; /* Remote memory the storage will read from / write to */
138 
139  ~init_storage_payload() override = default;
140  init_storage_payload() = default;
141  init_storage_payload(uint32_t task_count_,
142  uint32_t batch_size_,
143  uint32_t core_count_,
144  std::vector<uint8_t> mmap_export_blob_)
145  : task_count{task_count_},
146  batch_size{batch_size_},
147  core_count{core_count_},
148  mmap_export_blob{std::move(mmap_export_blob_)}
149  {
150  }
153  init_storage_payload &operator=(init_storage_payload const &) = default;
154  init_storage_payload &operator=(init_storage_payload &&) noexcept = default;
155 };
156 
157 /*
158  * RDMA connection details
159  */
160 struct rdma_connection_details_payload : public storage::control::message::payload {
161  uint32_t context_idx; /* Which context the connection should belong to */
162  storage::control::rdma_connection_role role; /* Role of the rdma connection */
163  std::vector<uint8_t> connection_details; /* Sender connection details */
164 
165  ~rdma_connection_details_payload() override = default;
167  explicit rdma_connection_details_payload(uint32_t context_idx_,
168  rdma_connection_role role_,
169  std::vector<uint8_t> connection_details_)
170  : context_idx{context_idx_},
171  role{role_},
172  connection_details{std::move(connection_details_)}
173  {
174  }
179 };
180 
181 /*
182  * Calculate the wire size of a control message header
183  *
184  * @message_header [in]: Message header
185  * @return: Wire size (in bytes) required to encode the header
186  */
187 uint32_t wire_size(storage::control::message_header const &hdr) noexcept;
188 
189 /*
190  * Calculate the wire size of a control message including its payload
191  *
192  * @message_header [in]: Message header
193  * @return: Wire size (in bytes) required to encode the message
194  */
195 uint32_t wire_size(storage::control::message const &msg);
196 
197 /*
198  * Encode a message header into a network byte order buffer
199  *
200  * @buffer [in]: Buffer to fill
201  * @hdr [in]: Header to encode
202  * @return: New position of the write buffer (ie buffer + wire_size(hdr)
203  */
204 char *encode(char *buffer, storage::control::message_header const &hdr) noexcept;
205 
206 /*
207  * Encode a message including its payload into a network byte order buffer
208  *
209  * @buffer [in]: Buffer to fill
210  * @msg [in]: Message to encode
211  * @return: New position of the write buffer (ie buffer + wire_size(msg)
212  */
213 char *encode(char *buffer, storage::control::message const &msg);
214 
215 /*
216  * Decode a message header from a network byte order buffer
217  *
218  * @buffer [in]: Buffer to read from
219  * @msg [in]: Header to decode into
220  * @return: New position of the read buffer (ie buffer + wire_size(msg)
221  */
222 char const *decode(char const *buffer, storage::control::message_header &hdr) noexcept;
223 
224 /*
225  * Decode a message including its payload from a network byte order buffer
226  *
227  * @buffer [in]: Buffer to read from
228  * @msg [in]: Message to decode into
229  * @return: New position of the read buffer (ie buffer + wire_size(msg)
230  */
231 char const *decode(char const *buffer, storage::control::message &msg);
232 
233 /*
234  * Convert a message_type enum to a string a user can read
235  *
236  * @type [in]: Enum to convert
237  * @return: User readable string
238  */
239 std::string to_string(storage::control::message_type type);
240 
241 /*
242  * Convert a rdma_connection_role enum to a string a user can read
243  *
244  * @role [in]: Enum to convert
245  * @return: User readable string
246  */
247 std::string to_string(storage::control::rdma_connection_role role);
248 
249 /*
250  * Convert a message to a string a user can read
251  *
252  * @msg [in]: Message to convert
253  * @return: User readable string
254  */
255 std::string to_string(storage::control::message const &msg);
256 
257 } // namespace storage::control
258 
259 #endif /* APPLICATIONS_STORAGE_STORAGE_COMMON_CONTROL_MESSAGE_HPP_ */
enum doca_error doca_error_t
DOCA API return codes.
uint32_t wire_size(storage::control::message_header const &hdr) noexcept
bool operator==(message_id const &lhs, message_id const &rhs)
char * encode(char *buffer, storage::control::message_header const &hdr) noexcept
char const * decode(char const *buffer, storage::control::message_header &hdr) noexcept
std::string to_string(storage::control::message_type type)
uint8_t type
Definition: packets.h:0
error_response_payload(error_response_payload const &)=default
error_response_payload(error_response_payload &&) noexcept=default
error_response_payload(doca_error_t error_code_, std::string message_)
init_storage_payload(init_storage_payload &&) noexcept=default
init_storage_payload(init_storage_payload const &)=default
init_storage_payload(uint32_t task_count_, uint32_t batch_size_, uint32_t core_count_, std::vector< uint8_t > mmap_export_blob_)
storage::control::correlation_id correlation_id
storage::control::message_id message_id
std::unique_ptr< storage::control::message::payload > payload
storage::control::message_type message_type
rdma_connection_details_payload(uint32_t context_idx_, rdma_connection_role role_, std::vector< uint8_t > connection_details_)
storage::control::rdma_connection_role role
rdma_connection_details_payload(rdma_connection_details_payload &&) noexcept=default
rdma_connection_details_payload(rdma_connection_details_payload const &)=default
storage_details_payload(storage_details_payload const &)=default
storage_details_payload(storage_details_payload &&) noexcept=default
storage_details_payload(uint64_t total_size_, uint32_t block_size_)