NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
comch_ctrl_path_client_sample.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023 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 #include <signal.h>
27 #include <stdbool.h>
28 #include <string.h>
29 #include <time.h>
30 #include <unistd.h>
31 
32 #include <doca_comch.h>
33 #include <doca_ctx.h>
34 #include <doca_dev.h>
35 #include <doca_error.h>
36 #include <doca_log.h>
37 #include <doca_pe.h>
38 
39 #include "comch_ctrl_path_common.h"
40 #include "common.h"
41 
42 DOCA_LOG_REGISTER(COMCH_CTRL_PATH_CLIENT);
43 
44 /* Sample's objects */
46  struct doca_dev *hw_dev; /* Device used in the sample */
47  struct doca_pe *pe; /* PE object used in the sample */
48  struct doca_comch_client *client; /* Client object used in the sample */
49  const char *text; /* Message to send to the server */
50  uint32_t text_len; /* Length of message to send to the server */
51  doca_error_t result; /* Holds result will be updated in callbacks */
52  bool finish; /* Controls whether progress loop should be run */
53 };
54 
62 static void send_task_completion_callback(struct doca_comch_task_send *task,
63  union doca_data task_user_data,
64  union doca_data ctx_user_data)
65 {
66  struct comch_ctrl_path_objects *sample_objects = (struct comch_ctrl_path_objects *)ctx_user_data.ptr;
67 
68  /* This argument is not in use */
69  (void)task_user_data;
70 
71  sample_objects->result = DOCA_SUCCESS;
72  DOCA_LOG_INFO("Task sent successfully");
73 
75 }
76 
84 static void send_task_completion_err_callback(struct doca_comch_task_send *task,
85  union doca_data task_user_data,
86  union doca_data ctx_user_data)
87 {
88  struct comch_ctrl_path_objects *sample_objects = (struct comch_ctrl_path_objects *)ctx_user_data.ptr;
89 
90  /* This argument is not in use */
91  (void)task_user_data;
92 
94  DOCA_LOG_ERR("Message failed to send with error = %s", doca_error_get_name(sample_objects->result));
95 
97  (void)doca_ctx_stop(doca_comch_client_as_ctx(sample_objects->client));
98 }
99 
108 static void message_recv_callback(struct doca_comch_event_msg_recv *event,
109  uint8_t *recv_buffer,
110  uint32_t msg_len,
111  struct doca_comch_connection *comch_connection)
112 {
113  union doca_data user_data = doca_comch_connection_get_user_data(comch_connection);
114  struct comch_ctrl_path_objects *sample_objects = (struct comch_ctrl_path_objects *)user_data.ptr;
115 
116  /* This argument is not in use */
117  (void)event;
118 
119  DOCA_LOG_INFO("Message received: '%.*s'", (int)msg_len, recv_buffer);
120 
121  (void)doca_ctx_stop(doca_comch_client_as_ctx(sample_objects->client));
122 }
123 
131 {
132  struct doca_comch_task_send *task;
133  struct doca_task *task_obj;
134  struct doca_comch_connection *connection;
136  union doca_data user_data;
137  const char *text = sample_objects->text;
138  size_t msg_len = sample_objects->text_len;
139 
140  result = doca_comch_client_get_connection(sample_objects->client, &connection);
141  if (result != DOCA_SUCCESS) {
142  DOCA_LOG_ERR("Failed to get connection from client with error = %s", doca_error_get_name(result));
143  return result;
144  }
145 
146  user_data.ptr = (void *)sample_objects;
147  result = doca_comch_connection_set_user_data(connection, user_data);
148  if (result != DOCA_SUCCESS) {
149  DOCA_LOG_ERR("Failed to set user_data for connection with error = %s", doca_error_get_name(result));
150  return result;
151  }
152 
153  result = doca_comch_client_task_send_alloc_init(sample_objects->client, connection, text, msg_len, &task);
154  if (result != DOCA_SUCCESS) {
155  DOCA_LOG_ERR("Failed to allocate task in client with error = %s", doca_error_get_name(result));
156  return result;
157  }
158 
159  task_obj = doca_comch_task_send_as_task(task);
160 
161  result = doca_task_submit(task_obj);
162  if (result != DOCA_SUCCESS) {
163  DOCA_LOG_ERR("Failed submitting send task with error = %s", doca_error_get_name(result));
164  doca_task_free(task_obj);
165  return result;
166  }
167 
168  return DOCA_SUCCESS;
169 }
170 
176 static void clean_comch_sample_objects(struct comch_ctrl_path_objects *sample_objects)
177 {
179 
180  clean_comch_ctrl_path_client(sample_objects->client, sample_objects->pe);
181  sample_objects->client = NULL;
182  sample_objects->pe = NULL;
183 
184  if (sample_objects->hw_dev != NULL) {
185  result = doca_dev_close(sample_objects->hw_dev);
186  if (result != DOCA_SUCCESS)
187  DOCA_LOG_ERR("Failed to close hw device properly with error = %s", doca_error_get_name(result));
188 
189  sample_objects->hw_dev = NULL;
190  }
191 }
192 
201 static void comch_client_state_changed_callback(const union doca_data user_data,
202  struct doca_ctx *ctx,
203  enum doca_ctx_states prev_state,
204  enum doca_ctx_states next_state)
205 {
206  (void)ctx;
207  (void)prev_state;
208 
209  struct comch_ctrl_path_objects *sample_objects = (struct comch_ctrl_path_objects *)user_data.ptr;
210 
211  switch (next_state) {
212  case DOCA_CTX_STATE_IDLE:
213  DOCA_LOG_INFO("CC client context has been stopped");
214  /* We can stop progressing the PE */
215  sample_objects->finish = true;
216  break;
221  DOCA_LOG_INFO("CC client context entered into starting state. Waiting for connection establishment");
222  break;
224  DOCA_LOG_INFO("CC client context is running. Sending message");
225  sample_objects->result = client_send_ping_pong(sample_objects);
226  if (sample_objects->result != DOCA_SUCCESS) {
227  DOCA_LOG_ERR("Failed to submit send task with error = %s",
228  doca_error_get_name(sample_objects->result));
229  (void)doca_ctx_stop(doca_comch_client_as_ctx(sample_objects->client));
230  }
231  break;
237  DOCA_LOG_INFO("CC client context entered into stopping state. Waiting for connection termination");
238  break;
239  default:
240  break;
241  }
242 }
243 
252 static doca_error_t init_comch_ctrl_path_objects(const char *server_name,
253  const char *dev_pci_addr,
254  struct comch_ctrl_path_objects *sample_objects)
255 {
258  .send_task_comp_err_cb = send_task_completion_err_callback,
259  .msg_recv_cb = message_recv_callback,
260  .data_path_mode = false,
261  .new_consumer_cb = NULL,
262  .expired_consumer_cb = NULL,
263  .ctx_user_data = sample_objects,
264  .ctx_state_changed_cb = comch_client_state_changed_callback};
265 
266  /* Open DOCA device according to the given PCI address */
267  result = open_doca_device_with_pci(dev_pci_addr, NULL, &(sample_objects->hw_dev));
268  if (result != DOCA_SUCCESS) {
269  DOCA_LOG_ERR("Failed to open Comm Channel DOCA device based on PCI address");
270  return result;
271  }
272 
273  result = init_comch_ctrl_path_client(server_name,
274  sample_objects->hw_dev,
275  &cfg,
276  &(sample_objects->client),
277  &(sample_objects->pe));
278  if (result != DOCA_SUCCESS) {
279  DOCA_LOG_ERR("Failed to init cc client with error = %s", doca_error_get_name(result));
280  clean_comch_sample_objects(sample_objects);
281  return result;
282  }
283 
284  return DOCA_SUCCESS;
285 }
286 
297  const char *dev_pci_addr,
298  const char *text,
299  const uint32_t text_len)
300 {
302  struct comch_ctrl_path_objects sample_objects = {0};
303  uint32_t max_msg_size;
304 
305  struct timespec ts = {
306  .tv_sec = 0,
307  .tv_nsec = SLEEP_IN_NANOS,
308  };
309 
310  result = init_comch_ctrl_path_objects(server_name, dev_pci_addr, &sample_objects);
311  if (result != DOCA_SUCCESS) {
312  DOCA_LOG_ERR("Failed to initialize sample with error = %s", doca_error_get_name(result));
313  clean_comch_sample_objects(&sample_objects);
314  return result;
315  }
316 
317  result = doca_comch_cap_get_max_msg_size(doca_dev_as_devinfo(sample_objects.hw_dev), &max_msg_size);
318  if (result != DOCA_SUCCESS) {
319  DOCA_LOG_ERR("Failed to get max supported message size with error = %s", doca_error_get_name(result));
320  clean_comch_sample_objects(&sample_objects);
321  return result;
322  }
323 
324  if (text_len > max_msg_size) {
325  DOCA_LOG_ERR(
326  "Failed to run sample, text size is larger than supported message size. text_len = %u, supported message size = %u",
327  text_len,
328  max_msg_size);
330  }
331 
332  sample_objects.text = text;
333  sample_objects.text_len = text_len;
334  sample_objects.finish = false;
335 
336  while (!sample_objects.finish) {
337  if (doca_pe_progress(sample_objects.pe) == 0)
338  nanosleep(&ts, &ts);
339  }
340 
341  clean_comch_sample_objects(&sample_objects);
342  return sample_objects.result;
343 }
#define NULL
Definition: __stddef_null.h:26
int32_t result
DOCA_LOG_REGISTER(COMCH_CTRL_PATH_CLIENT)
static void send_task_completion_callback(struct doca_comch_task_send *task, union doca_data task_user_data, union doca_data ctx_user_data)
static void send_task_completion_err_callback(struct doca_comch_task_send *task, union doca_data task_user_data, union doca_data ctx_user_data)
static void clean_comch_sample_objects(struct comch_ctrl_path_objects *sample_objects)
static doca_error_t init_comch_ctrl_path_objects(const char *server_name, const char *dev_pci_addr, struct comch_ctrl_path_objects *sample_objects)
static doca_error_t client_send_ping_pong(struct comch_ctrl_path_objects *sample_objects)
static void comch_client_state_changed_callback(const union doca_data user_data, struct doca_ctx *ctx, enum doca_ctx_states prev_state, enum doca_ctx_states next_state)
static void message_recv_callback(struct doca_comch_event_msg_recv *event, uint8_t *recv_buffer, uint32_t msg_len, struct doca_comch_connection *comch_connection)
doca_error_t start_comch_ctrl_path_client_sample(const char *server_name, const char *dev_pci_addr, const char *text, const uint32_t text_len)
doca_error_t init_comch_ctrl_path_client(const char *server_name, struct doca_dev *hw_dev, struct comch_ctrl_path_client_cb_config *cb_cfg, struct doca_comch_client **client, struct doca_pe **pe)
void clean_comch_ctrl_path_client(struct doca_comch_client *client, struct doca_pe *pe)
#define SLEEP_IN_NANOS
Definition: comch_utils.c:40
static doca_error_t open_doca_device_with_pci(const char *pcie_value, struct doca_dev **retval)
Definition: device.c:43
DOCA_STABLE doca_error_t doca_comch_client_get_connection(const struct doca_comch_client *comch_client, struct doca_comch_connection **connection)
DOCA_STABLE doca_error_t doca_comch_connection_set_user_data(struct doca_comch_connection *connection, union doca_data user_data)
DOCA_STABLE union doca_data doca_comch_connection_get_user_data(const struct doca_comch_connection *connection)
DOCA_STABLE struct doca_ctx * doca_comch_client_as_ctx(struct doca_comch_client *comch_client)
DOCA_STABLE doca_error_t doca_comch_client_task_send_alloc_init(struct doca_comch_client *comch_client, struct doca_comch_connection *peer, const void *msg, uint32_t len, struct doca_comch_task_send **task)
DOCA_STABLE doca_error_t doca_comch_cap_get_max_msg_size(const struct doca_devinfo *devinfo, uint32_t *size)
DOCA_STABLE struct doca_task * doca_comch_task_send_as_task(struct doca_comch_task_send *task)
DOCA_STABLE doca_error_t doca_ctx_stop(struct doca_ctx *ctx)
Stops the context allowing reconfiguration.
doca_ctx_states
This enum defines the states of a context.
Definition: doca_ctx.h:83
@ DOCA_CTX_STATE_STARTING
Definition: doca_ctx.h:93
@ DOCA_CTX_STATE_STOPPING
Definition: doca_ctx.h:106
@ DOCA_CTX_STATE_IDLE
Definition: doca_ctx.h:88
@ DOCA_CTX_STATE_RUNNING
Definition: doca_ctx.h:98
DOCA_STABLE struct doca_devinfo * doca_dev_as_devinfo(const struct doca_dev *dev)
Get local device info from device. This should be useful when wanting to query information about devi...
DOCA_STABLE doca_error_t doca_dev_close(struct doca_dev *dev)
Destroy allocated local device instance.
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_name(doca_error_t error)
Returns the string representation of an error code name.
@ DOCA_ERROR_INVALID_VALUE
Definition: doca_error.h:44
@ DOCA_SUCCESS
Definition: doca_error.h:38
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
Definition: doca_log.h:466
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
Definition: doca_log.h:486
DOCA_STABLE doca_error_t doca_task_get_status(const struct doca_task *task)
Get task status.
DOCA_STABLE doca_error_t doca_task_submit(struct doca_task *task)
Submit a task to a progress engine.
DOCA_STABLE uint8_t doca_pe_progress(struct doca_pe *pe)
Run the progress engine.
DOCA_STABLE void doca_task_free(struct doca_task *task)
Free a task back to where it was allocated from.
const struct ip_frag_config * cfg
Definition: ip_frag_dp.c:0
struct doca_comch_client * client
Convenience type for representing opaque data.
Definition: doca_types.h:56
void * ptr
Definition: doca_types.h:57
struct upf_accel_ctx * ctx