NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
secure_channel_core.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021-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 #include <arpa/inet.h>
27 #include <errno.h>
28 #include <signal.h>
29 #include <stdbool.h>
30 #include <string.h>
31 #include <sys/epoll.h>
32 #include <sys/signalfd.h>
33 
34 #include <doca_argp.h>
35 #include <doca_buf.h>
36 #include <doca_buf_inventory.h>
37 #include <doca_comch_consumer.h>
38 #include <doca_comch_producer.h>
39 #include <doca_ctx.h>
40 #include <doca_dev.h>
41 #include <doca_log.h>
42 #include <doca_mmap.h>
43 #include <doca_pe.h>
44 
45 #include <samples/common.h>
46 
47 #include <utils.h>
48 
49 #include "secure_channel_core.h"
50 
51 #define MAX_MSG_SIZE 65535 /* Max message size */
52 #define SLEEP_IN_NANOS (10 * 1000) /* Sample the connection every 10 microseconds */
53 #define MAX_FASTPATH_TASKS 1024 /* Maximum number of producer/consumer tasks to use */
54 #define CACHE_ALIGN 64 /* Cache line alignment for producer/consumer performance */
55 
56 #define NS_PER_SEC 1E9 /* Nano-seconds per second */
57 #define NS_PER_MSEC 1E6 /* Nano-seconds per millisecond */
58 #ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */
59 #define CLOCK_TYPE_ID CLOCK_MONOTONIC_RAW
60 #else
61 #define CLOCK_TYPE_ID CLOCK_MONOTONIC
62 #endif
63 
64 DOCA_LOG_REGISTER(SECURE_CHANNEL::Core);
65 
66 /* Local memory data for preparing and allocating doca_bufs */
68  struct doca_dev *dev; /* device associated with memory */
69  struct doca_mmap *mmap; /* mmap for registered memory */
70  struct doca_buf_inventory *inv; /* inventory to assign doca_bufs */
71  char *buf_data; /* allocated data to reference in bufs */
72 };
73 
74 /*
75  * ARGP Callback - Handle messages number parameter
76  *
77  * @param [in]: Input parameter
78  * @config [in/out]: Program configuration context
79  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
80  */
81 static doca_error_t messages_number_callback(void *param, void *config)
82 {
83  struct sc_config *app_cfg = (struct sc_config *)config;
84  int nb_send_msg = *(int *)param;
85 
86  if (nb_send_msg < 1) {
87  DOCA_LOG_ERR("Amount of messages to be sent by the client is less than 1");
89  }
90 
91  app_cfg->send_msg_nb = nb_send_msg;
92 
93  return DOCA_SUCCESS;
94 }
95 
96 /*
97  * ARGP Callback - Handle message size parameter
98  *
99  * @param [in]: Input parameter
100  * @config [in/out]: Program configuration context
101  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
102  */
103 static doca_error_t message_size_callback(void *param, void *config)
104 {
105  struct sc_config *app_cfg = (struct sc_config *)config;
106  int send_msg_size = *(int *)param;
107 
108  if (send_msg_size < 1 || send_msg_size > MAX_MSG_SIZE) {
109  DOCA_LOG_ERR("Received message size is not supported. Max is %u", MAX_MSG_SIZE);
111  }
112 
113  app_cfg->send_msg_size = send_msg_size;
114  return DOCA_SUCCESS;
115 }
116 
117 /*
118  * ARGP Callback - Handle Comm Channel DOCA device PCI address parameter
119  *
120  * @param [in]: Input parameter
121  * @config [in/out]: Program configuration context
122  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
123  */
124 static doca_error_t dev_pci_addr_callback(void *param, void *config)
125 {
126  struct sc_config *cfg = (struct sc_config *)config;
127  const char *dev_pci_addr = (char *)param;
128 
129  if (strnlen(dev_pci_addr, DOCA_DEVINFO_PCI_ADDR_SIZE) == DOCA_DEVINFO_PCI_ADDR_SIZE) {
130  DOCA_LOG_ERR("Entered device PCI address exceeding the maximum size of %d",
133  }
134 
135  strlcpy(cfg->cc_dev_pci_addr, dev_pci_addr, DOCA_DEVINFO_PCI_ADDR_SIZE);
136 
137  return DOCA_SUCCESS;
138 }
139 
140 /*
141  * ARGP Callback - Handle Comm Channel DOCA device representor PCI address parameter
142  *
143  * @param [in]: Input parameter
144  * @config [in/out]: Program configuration context
145  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
146  */
147 static doca_error_t rep_pci_addr_callback(void *param, void *config)
148 {
149  struct sc_config *cfg = (struct sc_config *)config;
150  const char *rep_pci_addr = (char *)param;
151 
152  if (cfg->mode == SC_MODE_DPU) {
153  if (strnlen(rep_pci_addr, DOCA_DEVINFO_REP_PCI_ADDR_SIZE) == DOCA_DEVINFO_REP_PCI_ADDR_SIZE) {
154  DOCA_LOG_ERR("Entered device representor PCI address exceeding the maximum size of %d",
157  }
158 
159  strlcpy(cfg->cc_dev_rep_pci_addr, rep_pci_addr, DOCA_DEVINFO_REP_PCI_ADDR_SIZE);
160  }
161 
162  return DOCA_SUCCESS;
163 }
164 
165 void new_consumer_callback(struct doca_comch_event_consumer *event,
166  struct doca_comch_connection *comch_connection,
167  uint32_t id)
168 {
170 
171  (void)event;
172 
173  cfg->consumer_id = id;
174 }
175 
176 void expired_consumer_callback(struct doca_comch_event_consumer *event,
177  struct doca_comch_connection *comch_connection,
178  uint32_t id)
179 {
180  /* Unused */
181 
182  (void)event;
183  (void)comch_connection;
184  (void)id;
185 }
186 
187 void comch_recv_event_cb(struct doca_comch_event_msg_recv *event,
188  uint8_t *recv_buffer,
189  uint32_t msg_len,
190  struct doca_comch_connection *comch_connection)
191 {
193  struct metadata_msg *meta;
194 
195  (void)event;
196 
197  /* Only messages received should be of type metadata_msg */
198  if (msg_len != sizeof(struct metadata_msg)) {
199  DOCA_LOG_ERR("Invalid message length detected: %u", msg_len);
200  // MOVE TO ERROR STATE - PERHAPS POPULATE A BAD VALUE IN MESSAGE FIELD
201  cfg->expected_msgs = -1;
202  return;
203  }
204 
205  meta = (struct metadata_msg *)recv_buffer;
206 
207  /* If an end message is received, set the expected messages back to 0 */
208  if (meta->type == END_MSG) {
209  cfg->expected_msgs = 0;
210  return;
211  }
212 
213  cfg->expected_msgs = ntohl(meta->num_msgs);
214  cfg->expected_msg_size = ntohl(meta->msg_size);
215 }
216 
217 /*
218  * Helper function to tear down local memory allocated with prepare_local_memory()
219  *
220  * @local_mem [out]: local memory data to destroy
221  */
222 static void destroy_local_memory(struct local_memory_bufs *local_mem)
223 {
224  (void)doca_dev_close(local_mem->dev);
225  free(local_mem->buf_data);
226  (void)doca_mmap_destroy(local_mem->mmap);
227  (void)doca_buf_inventory_destroy(local_mem->inv);
228 }
229 
230 /*
231  * Helper function to prepare local memory for use with doca_bufs and producer/consumer
232  *
233  * @local_mem [in]: struct of local memory data to be populated
234  * @pci_addr [in]: address of device to associate memory with
235  * @buf_len [in]: length of each buffer
236  * @num_bufs [in]: total number of buffers required
237  * @permissions [in]: bitwise combination of access flags - see enum doca_access_flag
238  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
239  */
241  const char *pci_addr,
242  size_t buf_len,
243  uint32_t num_bufs,
244  uint32_t permissions)
245 {
246  size_t data_length = buf_len * num_bufs;
247  size_t modulo;
249 
250  /* Open device to use for local memory registration */
251  result = open_doca_device_with_pci(pci_addr, NULL, &local_mem->dev);
252  if (result != DOCA_SUCCESS) {
253  DOCA_LOG_ERR("Failed to open device %s: %s", pci_addr, doca_error_get_descr(result));
254  return result;
255  }
256 
257  /* Aligned_alloc requires the length to be a multiple of the alignment value so may need to pad up */
258  modulo = data_length % CACHE_ALIGN;
259  local_mem->buf_data =
260  (char *)aligned_alloc(CACHE_ALIGN, data_length + (modulo == 0 ? 0 : CACHE_ALIGN - modulo));
261  if (local_mem->buf_data == NULL) {
262  DOCA_LOG_ERR("Failed allocate buffer memory of length: %lu", data_length);
264  goto close_dev;
265  }
266 
267  result = doca_mmap_create(&local_mem->mmap);
268  if (result != DOCA_SUCCESS) {
269  DOCA_LOG_ERR("Failed to create mmap: %s", doca_error_get_descr(result));
270  goto free_data;
271  }
272 
273  result = doca_mmap_set_permissions(local_mem->mmap, permissions);
274  if (result != DOCA_SUCCESS) {
275  DOCA_LOG_ERR("Failed to set permissions on mmap: %s", doca_error_get_descr(result));
276  goto destroy_mmap;
277  }
278 
279  result = doca_mmap_add_dev(local_mem->mmap, local_mem->dev);
280  if (result != DOCA_SUCCESS) {
281  DOCA_LOG_ERR("Failed to add device to mmap: %s", doca_error_get_descr(result));
282  goto destroy_mmap;
283  }
284 
285  result = doca_mmap_set_memrange(local_mem->mmap, local_mem->buf_data, data_length);
286  if (result != DOCA_SUCCESS) {
287  DOCA_LOG_ERR("Failed to set memrange of mmap: %s", doca_error_get_descr(result));
288  goto destroy_mmap;
289  }
290 
291  result = doca_mmap_start(local_mem->mmap);
292  if (result != DOCA_SUCCESS) {
293  DOCA_LOG_ERR("Failed to start mmap: %s", doca_error_get_descr(result));
294  goto destroy_mmap;
295  }
296 
297  result = doca_buf_inventory_create(num_bufs, &local_mem->inv);
298  if (result != DOCA_SUCCESS) {
299  DOCA_LOG_ERR("Failed to create buffer inventory: %s", doca_error_get_descr(result));
300  goto destroy_mmap;
301  }
302 
303  result = doca_buf_inventory_start(local_mem->inv);
304  if (result != DOCA_SUCCESS) {
305  DOCA_LOG_ERR("Failed to start buffer inventory: %s", doca_error_get_descr(result));
306  goto destroy_inv;
307  }
308 
309  return DOCA_SUCCESS;
310 
311 destroy_inv:
312  (void)doca_buf_inventory_destroy(local_mem->inv);
313 destroy_mmap:
314  (void)doca_mmap_destroy(local_mem->mmap);
315 free_data:
316  free(local_mem->buf_data);
317 close_dev:
318  (void)doca_dev_close(local_mem->dev);
319 
320  return result;
321 }
322 
323 /*
324  * Callback for successful send_task completion
325  *
326  * @task [in]: send_task that has completed
327  * @task_user_data [in]: task user data
328  * @ctx_user_data [in]: context user data
329  */
330 static void send_task_completed_callback(struct doca_comch_producer_task_send *task,
331  union doca_data task_user_data,
332  union doca_data ctx_user_data)
333 {
334  struct fast_path_ctx *producer_ctx = (struct fast_path_ctx *)ctx_user_data.ptr;
336 
337  (void)task_user_data;
338 
339  if (producer_ctx->state != FASTPATH_IN_PROGRESS)
340  return;
341 
342  (producer_ctx->completed_msgs)++;
343 
344  /* Move to a stopping state once enough messages have been confirmed as sent */
345  if (producer_ctx->completed_msgs == producer_ctx->total_msgs) {
346  producer_ctx->state = FASTPATH_COMPLETE;
347  return;
348  }
349 
350  /* Stop sending if enough messages are currently in flight */
351  if (producer_ctx->submitted_msgs == producer_ctx->total_msgs)
352  return;
353 
355  while (result == DOCA_ERROR_AGAIN) {
357  }
358 
359  if (result != DOCA_SUCCESS) {
360  DOCA_LOG_ERR("Failed to submit producer send task: %s", doca_error_get_descr(result));
361  producer_ctx->state = FASTPATH_ERROR;
362  }
363 
364  (producer_ctx->submitted_msgs)++;
365 }
366 
367 /*
368  * Callback for error on send_task completion
369  *
370  * @task [in]: send_task that has completed
371  * @task_user_data [in]: task user data
372  * @ctx_user_data [in]: context user data
373  */
374 static void send_task_fail_callback(struct doca_comch_producer_task_send *task,
375  union doca_data task_user_data,
376  union doca_data ctx_user_data)
377 {
378  struct fast_path_ctx *producer_ctx = (struct fast_path_ctx *)ctx_user_data.ptr;
379 
380  (void)task;
381  (void)task_user_data;
382 
383  /* Task fail errors may occur if context is in stopping state - this is expect */
384  if (producer_ctx->state == FASTPATH_COMPLETE)
385  return;
386 
387  DOCA_LOG_ERR("Received a producer send task completion error");
388  producer_ctx->state = FASTPATH_ERROR;
389 }
390 
391 /*
392  * Start a producer thread
393  *
394  * @context [in]: Input parameter
395  * @return: NULL (dummy return because of pthread requirement)
396  */
397 static void *run_producer(void *context)
398 {
399  struct doca_comch_producer_task_send *task[MAX_FASTPATH_TASKS] = {0};
400  struct cc_ctx *ctx = (struct cc_ctx *)context;
401  struct fast_path_ctx producer_ctx = {0};
402  union doca_data ctx_user_data = {0};
403  struct doca_comch_producer *producer;
404  struct local_memory_bufs local_mem;
405  struct doca_pe *producer_pe;
406  struct doca_buf *doca_buf;
407  enum doca_ctx_states state;
408  uint32_t total_msgs;
409  uint32_t total_tasks;
410  uint32_t msg_len;
411  uint32_t max_cap;
412  uint32_t i;
413  doca_error_t result, tmp_result;
414  struct timespec ts = {
415  .tv_nsec = SLEEP_IN_NANOS,
416  };
417 
418  /* Messages on producer are based on user input */
419  total_msgs = ctx->cfg->send_msg_nb;
420  msg_len = ctx->cfg->send_msg_size;
421 
422  /* If requested messages exceeds maximum tasks, tasks will be resubmitted in their completion callback */
423  total_tasks = (total_msgs > MAX_FASTPATH_TASKS) ? MAX_FASTPATH_TASKS : total_msgs;
424 
425  producer_ctx.total_msgs = total_msgs;
426 
427  /* Producer sends the same buffer repeatedly so only needs to allocate space for one */
428  result =
429  prepare_local_memory(&local_mem, ctx->cfg->cc_dev_pci_addr, msg_len, 1, DOCA_ACCESS_FLAG_PCI_READ_ONLY);
430  if (result != DOCA_SUCCESS) {
431  ctx->send_result->result = result;
432  goto exit_thread;
433  }
434 
435  /* Verify producer can support message size */
437  if (result != DOCA_SUCCESS) {
438  DOCA_LOG_ERR("Failed to query producer cap: %s", doca_error_get_descr(result));
439  goto destroy_local_mem;
440  }
441 
442  if (max_cap < msg_len) {
443  DOCA_LOG_ERR("Producer does not support message size. Requested: %u, max: %u", msg_len, max_cap);
445  goto destroy_local_mem;
446  }
447 
448  result = doca_pe_create(&producer_pe);
449  if (result != DOCA_SUCCESS) {
450  DOCA_LOG_ERR("Failed to create producer progress engine: %s", doca_error_get_descr(result));
451  goto destroy_local_mem;
452  }
453 
454  result = doca_comch_producer_create(ctx->comch_connection, &producer);
455  if (result != DOCA_SUCCESS) {
456  DOCA_LOG_ERR("Failed to create producer: %s", doca_error_get_descr(result));
457  goto destroy_pe;
458  }
459 
460  result = doca_pe_connect_ctx(producer_pe, doca_comch_producer_as_ctx(producer));
461  if (result != DOCA_SUCCESS) {
462  DOCA_LOG_ERR("Failed to connect producer to pe: %s", doca_error_get_descr(result));
463  goto destroy_producer;
464  }
465 
469  total_tasks);
470  if (result != DOCA_SUCCESS) {
471  DOCA_LOG_ERR("Failed to configure producer send tasks: %s", doca_error_get_descr(result));
472  goto destroy_pe;
473  }
474 
475  /* Add user data to update context from callbacks */
476  ctx_user_data.ptr = &producer_ctx;
477  result = doca_ctx_set_user_data(doca_comch_producer_as_ctx(producer), ctx_user_data);
478  if (result != DOCA_SUCCESS) {
479  DOCA_LOG_ERR("Failed to set producer user data: %s", doca_error_get_descr(result));
480  goto destroy_pe;
481  }
482 
484  if (result != DOCA_SUCCESS) {
485  DOCA_LOG_ERR("Failed to start producer: %s", doca_error_get_descr(result));
486  goto destroy_pe;
487  }
488 
489  /* Allocate a single buffer from registered local memory */
491  local_mem.mmap,
492  local_mem.buf_data,
493  msg_len,
494  &doca_buf);
495  if (result != DOCA_SUCCESS) {
496  DOCA_LOG_ERR("Failed to configure producer send tasks: %s", doca_error_get_descr(result));
497  goto stop_producer;
498  }
499 
500  /*
501  * Wait on external consumer to come up.
502  * This is handled in the comch progress_engine.
503  */
504  while (ctx->consumer_id == 0) {
505  nanosleep(&ts, &ts);
506  }
507 
508  producer_ctx.state = FASTPATH_IN_PROGRESS;
509 
510  if (clock_gettime(CLOCK_TYPE_ID, &producer_ctx.start_time) != 0)
511  DOCA_LOG_ERR("Failed to get timestamp");
512 
513  /* Allocate and submit max number of tasks */
514  for (i = 0; i < total_tasks; i++) {
516  doca_buf,
517  NULL,
518  0,
519  ctx->consumer_id,
520  &task[i]);
521  if (result != DOCA_SUCCESS) {
522  DOCA_LOG_ERR("Failed to allocate a producer task: %s", doca_error_get_descr(result));
523  goto free_tasks;
524  }
525 
526  /* May need to wait for a post_recv message before being able to send */
528  while (result == DOCA_ERROR_AGAIN) {
530  }
531 
532  if (result != DOCA_SUCCESS) {
533  DOCA_LOG_ERR("Failed to submit producer send task: %s", doca_error_get_descr(result));
534  goto free_tasks;
535  }
536 
537  (producer_ctx.submitted_msgs)++;
538  }
539 
540  /* Progress until all messages have been sent or an error occurred */
541  while (producer_ctx.state == FASTPATH_IN_PROGRESS)
542  doca_pe_progress(producer_pe);
543 
544  if (clock_gettime(CLOCK_TYPE_ID, &producer_ctx.end_time) != 0)
545  DOCA_LOG_ERR("Failed to get timestamp");
546 
547  if (producer_ctx.state == FASTPATH_ERROR) {
549  DOCA_LOG_ERR("Producer datapath failed");
550  }
551 
552 free_tasks:
553  /* Free all allocated tasks */
554  for (i = 0; i < total_tasks; i++)
555  if (task[i] != NULL)
557 
558  doca_buf_dec_refcount(doca_buf, NULL);
559 
560 stop_producer:
561  tmp_result = doca_ctx_stop(doca_comch_producer_as_ctx(producer));
562  if (tmp_result != DOCA_ERROR_IN_PROGRESS && tmp_result != DOCA_SUCCESS) {
563  DOCA_LOG_ERR("Failed to stop producer: %s", doca_error_get_descr(tmp_result));
564  goto destroy_producer;
565  }
566 
567  /* Wait for producer stop to complete */
568  (void)doca_ctx_get_state(doca_comch_producer_as_ctx(producer), &state);
569  while (state != DOCA_CTX_STATE_IDLE) {
570  (void)doca_pe_progress(producer_pe);
571  nanosleep(&ts, &ts);
572  (void)doca_ctx_get_state(doca_comch_producer_as_ctx(producer), &state);
573  }
574 
575 destroy_producer:
576  tmp_result = doca_comch_producer_destroy(producer);
577  if (tmp_result != DOCA_SUCCESS)
578  DOCA_LOG_ERR("Failed to destroy producer: %s", doca_error_get_descr(tmp_result));
579 destroy_pe:
580  tmp_result = doca_pe_destroy(producer_pe);
581  if (tmp_result != DOCA_SUCCESS)
582  DOCA_LOG_ERR("Failed to destroy producer pe: %s", doca_error_get_descr(tmp_result));
583 destroy_local_mem:
584  destroy_local_memory(&local_mem);
585 
586 exit_thread:
587  ctx->send_result->processed_msgs = producer_ctx.completed_msgs;
588  ctx->send_result->start_time = producer_ctx.start_time;
589  ctx->send_result->end_time = producer_ctx.end_time;
590  ctx->send_result->result = result;
591 
592  atomic_fetch_sub(&ctx->active_threads, 1);
593 
594  return NULL;
595 }
596 
597 /*
598  * Callback for successful post_recv completion
599  *
600  * @task [in]: post_recv task that has completed
601  * @task_user_data [in]: task user data
602  * @ctx_user_data [in]: context user data
603  */
604 static void recv_task_completed_callback(struct doca_comch_consumer_task_post_recv *task,
605  union doca_data task_user_data,
606  union doca_data ctx_user_data)
607 {
608  struct fast_path_ctx *consumer_ctx = (struct fast_path_ctx *)ctx_user_data.ptr;
609  struct doca_buf *buf;
611 
612  (void)task_user_data;
613 
614  /* Take timestamp of first message received */
615  if (consumer_ctx->completed_msgs == 0) {
616  if (clock_gettime(CLOCK_TYPE_ID, &consumer_ctx->start_time) != 0)
617  DOCA_LOG_ERR("Failed to get timestamp");
618  }
619 
620  (consumer_ctx->completed_msgs)++;
621 
622  if (consumer_ctx->completed_msgs == consumer_ctx->total_msgs)
623  consumer_ctx->state = FASTPATH_COMPLETE;
624 
626 
627  /* Reset the buffer length so that it can be fully repopulated */
629  if (result != DOCA_SUCCESS) {
630  DOCA_LOG_ERR("Failed to reset doca_buf length: %s", doca_error_get_descr(result));
631  consumer_ctx->state = FASTPATH_ERROR;
632  return;
633  }
634 
635  /* Resubmit post recv task */
637  if (result != DOCA_SUCCESS) {
638  DOCA_LOG_ERR("Failed to resubmit post_recv task: %s", doca_error_get_descr(result));
639  consumer_ctx->state = FASTPATH_ERROR;
640  }
641 }
642 
643 /*
644  * Callback for error on post_recv completion
645  *
646  * @task [in]: post_recv task that has completed
647  * @task_user_data [in]: task user data
648  * @ctx_user_data [in]: context user data
649  */
650 static void recv_task_fail_callback(struct doca_comch_consumer_task_post_recv *task,
651  union doca_data task_user_data,
652  union doca_data ctx_user_data)
653 {
654  struct fast_path_ctx *consumer_ctx = (struct fast_path_ctx *)ctx_user_data.ptr;
655 
656  (void)task;
657  (void)task_user_data;
658 
659  /* Task fail errors may occur if context is in stopping state - this is expect */
660  if (consumer_ctx->state == FASTPATH_COMPLETE)
661  return;
662 
663  DOCA_LOG_ERR("Received a consumer post recv completion error");
664  consumer_ctx->state = FASTPATH_ERROR;
665 }
666 
667 /*
668  * Start a consumer thread
669  *
670  * @context [in]: Input parameter
671  * @return: NULL (dummy return because of pthread requirement)
672  */
673 static void *run_consumer(void *context)
674 {
675  struct doca_comch_consumer_task_post_recv *task[MAX_FASTPATH_TASKS] = {0};
676  struct cc_ctx *ctx = (struct cc_ctx *)context;
677  struct doca_buf *doca_buf[MAX_FASTPATH_TASKS] = {0};
678  struct doca_comch_consumer *consumer;
679  struct fast_path_ctx consumer_ctx = {0};
680  union doca_data ctx_user_data = {0};
681  struct local_memory_bufs local_mem;
682  struct doca_pe *consumer_pe;
683  enum doca_ctx_states state;
684  uint32_t total_msgs;
685  uint32_t total_tasks;
686  uint32_t msg_len;
687  uint32_t max_cap;
688  uint32_t i;
689  doca_error_t result, tmp_result;
690  struct timespec ts = {
691  .tv_nsec = SLEEP_IN_NANOS,
692  };
693 
694  /* Messages expected by consumer are based metadata received from opposite side */
695  total_msgs = ctx->expected_msgs;
696  msg_len = ctx->expected_msg_size;
697 
698  /* If expected receive messages exceeds maximum tasks, tasks will be reused as post_recv */
699  total_tasks = (total_msgs > MAX_FASTPATH_TASKS) ? MAX_FASTPATH_TASKS : total_msgs;
700 
701  consumer_ctx.total_msgs = total_msgs;
702 
703  /* Consumer allocates a buffer of expected length for every task - must have write access */
704  result = prepare_local_memory(&local_mem,
705  ctx->cfg->cc_dev_pci_addr,
706  msg_len,
707  total_tasks,
709  if (result != DOCA_SUCCESS) {
710  ctx->recv_result->result = result;
711  goto exit_thread;
712  }
713 
714  /* Verify consumer can support message size */
716  if (result != DOCA_SUCCESS) {
717  DOCA_LOG_ERR("Failed to query consumer cap: %s", doca_error_get_descr(result));
718  goto destroy_local_mem;
719  }
720 
721  if (max_cap < msg_len) {
722  DOCA_LOG_ERR("Consumer does not support message size. Requested: %u, max: %u", msg_len, max_cap);
724  goto destroy_local_mem;
725  }
726 
727  result = doca_pe_create(&consumer_pe);
728  if (result != DOCA_SUCCESS) {
729  DOCA_LOG_ERR("Failed to create consumer progress engine: %s", doca_error_get_descr(result));
730  goto destroy_local_mem;
731  }
732 
733  result = doca_comch_consumer_create(ctx->comch_connection, local_mem.mmap, &consumer);
734  if (result != DOCA_SUCCESS) {
735  DOCA_LOG_ERR("Failed to create consumer: %s", doca_error_get_descr(result));
736  goto destroy_pe;
737  }
738 
739  result = doca_pe_connect_ctx(consumer_pe, doca_comch_consumer_as_ctx(consumer));
740  if (result != DOCA_SUCCESS) {
741  DOCA_LOG_ERR("Failed to connect consumer to pe: %s", doca_error_get_descr(result));
742  goto destroy_consumer;
743  }
744 
748  total_tasks);
749  if (result != DOCA_SUCCESS) {
750  DOCA_LOG_ERR("Failed to configure consumer send tasks: %s", doca_error_get_descr(result));
751  goto destroy_pe;
752  }
753 
754  /* Add user data to update context from callbacks */
755  ctx_user_data.ptr = &consumer_ctx;
756  result = doca_ctx_set_user_data(doca_comch_consumer_as_ctx(consumer), ctx_user_data);
757  if (result != DOCA_SUCCESS) {
758  DOCA_LOG_ERR("Failed to set consumer user data: %s", doca_error_get_descr(result));
759  goto destroy_pe;
760  }
761 
764  DOCA_LOG_ERR("Failed to start consumer: %s", doca_error_get_descr(result));
765  goto destroy_pe;
766  }
767 
768  /* Wait for consumer start to complete */
769  (void)doca_ctx_get_state(doca_comch_consumer_as_ctx(consumer), &state);
770  while (state != DOCA_CTX_STATE_RUNNING) {
771  (void)doca_pe_progress(consumer_pe);
772  nanosleep(&ts, &ts);
773  (void)doca_ctx_get_state(doca_comch_consumer_as_ctx(consumer), &state);
774  }
775 
776  consumer_ctx.state = FASTPATH_IN_PROGRESS;
777 
778  /* Assign a buffer and submit a post_recv message for every available task */
779  for (i = 0; i < total_tasks; i++) {
781  local_mem.mmap,
782  local_mem.buf_data + (i * msg_len),
783  msg_len,
784  &doca_buf[i]);
785  if (result != DOCA_SUCCESS) {
786  DOCA_LOG_ERR("Failed to allocate a consumer buf: %s", doca_error_get_descr(result));
787  goto free_task_and_bufs;
788  }
789 
790  result = doca_comch_consumer_task_post_recv_alloc_init(consumer, doca_buf[i], &task[i]);
791  if (result != DOCA_SUCCESS) {
792  DOCA_LOG_ERR("Failed to allocate a post recv task: %s", doca_error_get_descr(result));
793  goto free_task_and_bufs;
794  }
795 
797  if (result != DOCA_SUCCESS) {
798  DOCA_LOG_ERR("Failed to submit consumer post recv task: %s", doca_error_get_descr(result));
799  goto free_task_and_bufs;
800  }
801  }
802 
803  /* Progress until all expected messages have been received or an error occurred */
804  while (consumer_ctx.state == FASTPATH_IN_PROGRESS) {
805  doca_pe_progress(consumer_pe);
806  }
807 
808  if (clock_gettime(CLOCK_TYPE_ID, &consumer_ctx.end_time) != 0)
809  DOCA_LOG_ERR("Failed to get timestamp");
810 
811  if (consumer_ctx.state == FASTPATH_ERROR) {
813  DOCA_LOG_ERR("Consumer datapath failed");
814  }
815 
816 free_task_and_bufs:
817  /* Free all allocated buffers and tasks */
818  for (i = 0; i < total_tasks; i++) {
819  if (doca_buf[i] != NULL)
820  doca_buf_dec_refcount(doca_buf[i], NULL);
821  if (task[i] != NULL)
823  }
824 
825  tmp_result = doca_ctx_stop(doca_comch_consumer_as_ctx(consumer));
826  if (tmp_result != DOCA_ERROR_IN_PROGRESS && tmp_result != DOCA_SUCCESS) {
827  DOCA_LOG_ERR("Failed to stop consumer: %s", doca_error_get_descr(tmp_result));
828  goto destroy_consumer;
829  }
830 
831  /* Wait for consumer stop to complete */
832  (void)doca_ctx_get_state(doca_comch_consumer_as_ctx(consumer), &state);
833  while (state != DOCA_CTX_STATE_IDLE) {
834  (void)doca_pe_progress(consumer_pe);
835  nanosleep(&ts, &ts);
836  (void)doca_ctx_get_state(doca_comch_consumer_as_ctx(consumer), &state);
837  }
838 
839 destroy_consumer:
840  tmp_result = doca_comch_consumer_destroy(consumer);
841  if (tmp_result != DOCA_SUCCESS)
842  DOCA_LOG_ERR("Failed to destroy consumer: %s", doca_error_get_descr(tmp_result));
843 
844 destroy_pe:
845  tmp_result = doca_pe_destroy(consumer_pe);
846  if (tmp_result != DOCA_SUCCESS)
847  DOCA_LOG_ERR("Failed to destroy consumer pe: %s", doca_error_get_descr(tmp_result));
848 
849 destroy_local_mem:
850  destroy_local_memory(&local_mem);
851 
852 exit_thread:
853  ctx->recv_result->processed_msgs = consumer_ctx.completed_msgs;
854  ctx->recv_result->start_time = consumer_ctx.start_time;
855  ctx->recv_result->end_time = consumer_ctx.end_time;
856  ctx->recv_result->result = result;
857 
858  atomic_fetch_sub(&ctx->active_threads, 1);
859 
860  return NULL;
861 }
862 
863 /*
864  * Start threads and wait for them to finish
865  *
866  * @ctx [in]: Thread context
867  * @comch_cfg [in]: Comch channel to progress on
868  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
869  */
871 {
873  int running_threads;
874 
875  /* set count to determine when threads have finished */
876  atomic_init(&ctx->active_threads, 2);
877  running_threads = 2;
878 
879  if (pthread_create(ctx->sendto_t, NULL, run_producer, (void *)ctx) != 0) {
880  DOCA_LOG_ERR("Failed to start sendto thread");
881  return DOCA_ERROR_BAD_STATE;
882  }
883 
884  if (pthread_detach(*ctx->sendto_t) != 0) {
885  DOCA_LOG_ERR("Failed to detach sendto thread");
886  return DOCA_ERROR_BAD_STATE;
887  }
888 
889  if (pthread_create(ctx->recvfrom_t, NULL, run_consumer, (void *)ctx) != 0) {
890  DOCA_LOG_ERR("Failed to start recvfrom thread");
891  return DOCA_ERROR_BAD_STATE;
892  }
893 
894  if (pthread_detach(*ctx->recvfrom_t) != 0) {
895  DOCA_LOG_ERR("Failed to detach sendto thread");
896  return DOCA_ERROR_BAD_STATE;
897  }
898 
899  /*
900  * Progress the comch PE while waiting for the threads to finish.
901  * Comch handles producer and consumer control messages so must continue to run.
902  */
903  while (running_threads > 0) {
905  if (result != DOCA_SUCCESS) {
906  DOCA_LOG_ERR("Error in comch progression: %s", doca_error_get_descr(result));
907  return result;
908  }
909  running_threads = atomic_load(&ctx->active_threads);
910  }
911 
912  return DOCA_SUCCESS;
913 }
914 
915 /*
916  * Helper to calculate time difference between two timespec structs
917  *
918  * @end [in]: end time
919  * @start [in]: start time
920  * @return: time difference in milliseconds
921  */
922 static double calculate_timediff_ms(struct timespec *end, struct timespec *start)
923 {
924  long diff;
925 
926  diff = (end->tv_sec - start->tv_sec) * NS_PER_SEC;
927  diff += end->tv_nsec;
928  diff -= start->tv_nsec;
929 
930  return (double)(diff / NS_PER_MSEC);
931 }
932 
934 {
935  struct t_results send_result = {0};
936  struct t_results recv_result = {0};
937  pthread_t sendto_thread, recvfrom_thread;
939  struct metadata_msg meta = {0};
940 
941  ctx->comch_connection = comch_util_get_connection(comch_cfg);
942  ctx->cfg = cfg;
943 
944  /* Send a comch metadata message to the other side indicating the number of fastpath messages */
945  meta.type = START_MSG;
946  meta.num_msgs = htonl(cfg->send_msg_nb);
947  meta.msg_size = htonl(cfg->send_msg_size);
949  if (result != DOCA_SUCCESS) {
950  DOCA_LOG_ERR("Failed to send metadata message: %s", doca_error_get_descr(result));
951  return result;
952  }
953 
954  /* Wait until the metadata message from the opposite side has been received */
955  while (ctx->expected_msgs == 0) {
957  if (result != DOCA_SUCCESS) {
958  DOCA_LOG_ERR("Failed to progress comch: %s", doca_error_get_descr(result));
959  return result;
960  }
961  }
962 
963  if (ctx->expected_msgs < 0) {
964  DOCA_LOG_ERR("Got a bad metadata message on comch");
966  }
967 
968  ctx->sendto_t = &sendto_thread;
969  ctx->recvfrom_t = &recvfrom_thread;
970  ctx->send_result = &send_result;
971  ctx->recv_result = &recv_result;
972 
974  if (result != DOCA_SUCCESS) {
975  return result;
976  }
977 
978  result = ctx->send_result->result;
979  if (result != DOCA_SUCCESS) {
980  DOCA_LOG_ERR("Send thread finished unsuccessfully");
981  return result;
982  }
983 
984  result = ctx->recv_result->result;
985  if (result != DOCA_SUCCESS) {
986  DOCA_LOG_ERR("Receive thread finished unsuccessfully");
987  return result;
988  }
989 
990  /*
991  * To ensure that both sides have finished with the comch channel send an end message from DPU to host.
992  * On the host side, wait to receive said message (sets expected msgs back to 0).
993  * Comch utils enforces that the client must disconnect from the server before it can be destroyed.
994  */
995  if (cfg->mode == SC_MODE_DPU) {
996  meta.type = END_MSG;
998  if (result != DOCA_SUCCESS) {
999  DOCA_LOG_ERR("Failed to send metadata message: %s", doca_error_get_descr(result));
1000  return result;
1001  }
1002  } else {
1003  while (ctx->expected_msgs != 0) {
1005  if (result != DOCA_SUCCESS) {
1006  DOCA_LOG_ERR("Failed to progress comch: %s", doca_error_get_descr(result));
1007  return result;
1008  }
1009  }
1010  }
1011 
1012  DOCA_LOG_INFO("Producer sent %u messages in approximately %0.4f milliseconds",
1013  ctx->send_result->processed_msgs,
1014  calculate_timediff_ms(&ctx->send_result->end_time, &ctx->send_result->start_time));
1015  DOCA_LOG_INFO("Consumer received %u messages in approximately %0.4f milliseconds",
1016  ctx->recv_result->processed_msgs,
1017  calculate_timediff_ms(&ctx->recv_result->end_time, &ctx->recv_result->start_time));
1018 
1019  return result;
1020 }
1021 
1023 {
1025 
1026  struct doca_argp_param *message_size_param, *messages_number_param, *pci_addr_param, *rep_pci_addr_param;
1027 
1028  /* Create and register message to send param */
1029  result = doca_argp_param_create(&message_size_param);
1030  if (result != DOCA_SUCCESS) {
1031  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
1032  return result;
1033  }
1034  doca_argp_param_set_short_name(message_size_param, "s");
1035  doca_argp_param_set_long_name(message_size_param, "msg-size");
1036  doca_argp_param_set_description(message_size_param, "Message size to be sent");
1038  doca_argp_param_set_type(message_size_param, DOCA_ARGP_TYPE_INT);
1039  doca_argp_param_set_mandatory(message_size_param);
1040  result = doca_argp_register_param(message_size_param);
1041  if (result != DOCA_SUCCESS) {
1042  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
1043  return result;
1044  }
1045 
1046  /* Create and register number of message param */
1047  result = doca_argp_param_create(&messages_number_param);
1048  if (result != DOCA_SUCCESS) {
1049  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
1050  return result;
1051  }
1052  doca_argp_param_set_short_name(messages_number_param, "n");
1053  doca_argp_param_set_long_name(messages_number_param, "num-msgs");
1054  doca_argp_param_set_description(messages_number_param, "Number of messages to be sent");
1056  doca_argp_param_set_type(messages_number_param, DOCA_ARGP_TYPE_INT);
1057  doca_argp_param_set_mandatory(messages_number_param);
1058  result = doca_argp_register_param(messages_number_param);
1059  if (result != DOCA_SUCCESS) {
1060  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
1061  return result;
1062  }
1063 
1064  /* Create and register Comm Channel DOCA device PCI address */
1065  result = doca_argp_param_create(&pci_addr_param);
1066  if (result != DOCA_SUCCESS) {
1067  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
1068  return result;
1069  }
1070  doca_argp_param_set_short_name(pci_addr_param, "p");
1071  doca_argp_param_set_long_name(pci_addr_param, "pci-addr");
1072  doca_argp_param_set_description(pci_addr_param, "DOCA Comch device PCI address");
1075  doca_argp_param_set_mandatory(pci_addr_param);
1076  result = doca_argp_register_param(pci_addr_param);
1077  if (result != DOCA_SUCCESS) {
1078  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
1079  return result;
1080  }
1081 
1082  /* Create and register Comm Channel DOCA device representor PCI address */
1083  result = doca_argp_param_create(&rep_pci_addr_param);
1084  if (result != DOCA_SUCCESS) {
1085  DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
1086  return result;
1087  }
1088  doca_argp_param_set_short_name(rep_pci_addr_param, "r");
1089  doca_argp_param_set_long_name(rep_pci_addr_param, "rep-pci");
1090  doca_argp_param_set_description(rep_pci_addr_param,
1091  "DOCA Comch device representor PCI address (needed only on DPU)");
1093  doca_argp_param_set_type(rep_pci_addr_param, DOCA_ARGP_TYPE_STRING);
1094  result = doca_argp_register_param(rep_pci_addr_param);
1095  if (result != DOCA_SUCCESS) {
1096  DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
1097  return result;
1098  }
1099 
1100  /* Register version callback for DOCA SDK & RUNTIME */
1102  if (result != DOCA_SUCCESS) {
1103  DOCA_LOG_ERR("Failed to register version callback: %s", doca_error_get_descr(result));
1104  return result;
1105  }
1106 
1107  return DOCA_SUCCESS;
1108 }
#define NULL
Definition: __stddef_null.h:26
int32_t result
void * comch_utils_get_user_data(struct doca_comch_connection *connection)
Definition: comch_utils.c:254
doca_error_t comch_utils_progress_connection(struct doca_comch_connection *connection)
Definition: comch_utils.c:264
struct doca_comch_connection * comch_util_get_connection(struct comch_cfg *comch_cfg)
Definition: comch_utils.c:276
doca_error_t comch_utils_send(struct doca_comch_connection *connection, const void *msg, uint32_t len)
Definition: comch_utils.c:212
static doca_error_t open_doca_device_with_pci(const char *pcie_value, struct doca_dev **retval)
Definition: device.c:43
static struct app_gpu_cfg app_cfg
DOCA_EXPERIMENTAL void doca_argp_param_set_description(struct doca_argp_param *param, const char *description)
Set the description of the program param, used during program usage.
DOCA_EXPERIMENTAL void doca_argp_param_set_long_name(struct doca_argp_param *param, const char *name)
Set the long name of the program param.
DOCA_EXPERIMENTAL void doca_argp_param_set_callback(struct doca_argp_param *param, doca_argp_param_cb_t callback)
Set the callback function of the program param.
DOCA_EXPERIMENTAL void doca_argp_param_set_mandatory(struct doca_argp_param *param)
Mark the program param as mandatory.
DOCA_EXPERIMENTAL doca_error_t doca_argp_param_create(struct doca_argp_param **param)
Create new program param.
DOCA_EXPERIMENTAL void doca_argp_param_set_type(struct doca_argp_param *param, enum doca_argp_type type)
Set the type of the param arguments.
DOCA_EXPERIMENTAL doca_error_t doca_argp_register_version_callback(doca_argp_param_cb_t callback)
Register an alternative version callback.
DOCA_EXPERIMENTAL void doca_argp_param_set_short_name(struct doca_argp_param *param, const char *name)
Set the short name of the program param.
DOCA_EXPERIMENTAL doca_error_t doca_argp_register_param(struct doca_argp_param *input_param)
Register a program flag.
@ DOCA_ARGP_TYPE_STRING
Definition: doca_argp.h:56
@ DOCA_ARGP_TYPE_INT
Definition: doca_argp.h:57
DOCA_STABLE doca_error_t doca_buf_inventory_destroy(struct doca_buf_inventory *inventory)
Destroy buffer inventory structure.
static doca_error_t doca_buf_inventory_buf_get_by_addr(struct doca_buf_inventory *inventory, struct doca_mmap *mmap, void *addr, size_t len, struct doca_buf **buf)
Allocate single element from buffer inventory and point it to the buffer defined by addr & len argume...
static doca_error_t doca_buf_inventory_buf_get_by_data(struct doca_buf_inventory *inventory, struct doca_mmap *mmap, void *data, size_t data_len, struct doca_buf **buf)
Allocate single element from buffer inventory and point it to the buffer defined by data & data_len a...
DOCA_STABLE doca_error_t doca_buf_inventory_start(struct doca_buf_inventory *inventory)
Start element retrieval from inventory.
DOCA_STABLE doca_error_t doca_buf_inventory_create(size_t num_elements, struct doca_buf_inventory **inventory)
Allocates buffer inventory with default/unset attributes.
DOCA_STABLE doca_error_t doca_buf_dec_refcount(struct doca_buf *buf, uint16_t *refcount)
Decrease the object reference count by 1, if 0 reached, return the element back to the inventory.
DOCA_STABLE doca_error_t doca_buf_reset_data_len(struct doca_buf *buf)
DOCA_STABLE struct doca_buf * doca_comch_consumer_task_post_recv_get_buf(const struct doca_comch_consumer_task_post_recv *task)
DOCA_STABLE doca_error_t doca_comch_consumer_create(struct doca_comch_connection *comch_connection, struct doca_mmap *buf_mmap, struct doca_comch_consumer **consumer)
DOCA_STABLE doca_error_t doca_comch_consumer_destroy(struct doca_comch_consumer *consumer)
DOCA_STABLE doca_error_t doca_comch_consumer_task_post_recv_set_conf(struct doca_comch_consumer *consumer, doca_comch_consumer_task_post_recv_completion_cb_t task_completion_cb, doca_comch_consumer_task_post_recv_completion_cb_t task_error_cb, uint32_t num_post_recv_tasks)
DOCA_STABLE doca_error_t doca_comch_consumer_task_post_recv_alloc_init(struct doca_comch_consumer *consumer, struct doca_buf *buf, struct doca_comch_consumer_task_post_recv **task)
Allocate and initialize a doca_consumer post receive task.
DOCA_STABLE struct doca_ctx * doca_comch_consumer_as_ctx(struct doca_comch_consumer *consumer)
DOCA_STABLE struct doca_task * doca_comch_consumer_task_post_recv_as_task(struct doca_comch_consumer_task_post_recv *task)
DOCA_STABLE doca_error_t doca_comch_consumer_cap_get_max_buf_size(const struct doca_devinfo *devinfo, uint32_t *max_buf_size)
DOCA_STABLE doca_error_t doca_comch_producer_create(struct doca_comch_connection *comch_connection, struct doca_comch_producer **producer)
DOCA_STABLE struct doca_task * doca_comch_producer_task_send_as_task(struct doca_comch_producer_task_send *task)
DOCA_STABLE doca_error_t doca_comch_producer_task_send_set_conf(struct doca_comch_producer *producer, doca_comch_producer_task_send_completion_cb_t task_completion_cb, doca_comch_producer_task_send_completion_cb_t task_error_cb, uint32_t num_send_tasks)
DOCA_STABLE doca_error_t doca_comch_producer_destroy(struct doca_comch_producer *producer)
DOCA_STABLE doca_error_t doca_comch_producer_cap_get_max_buf_size(const struct doca_devinfo *devinfo, uint32_t *max_buf_size)
DOCA_STABLE struct doca_ctx * doca_comch_producer_as_ctx(struct doca_comch_producer *producer)
DOCA_STABLE doca_error_t doca_comch_producer_task_send_alloc_init(struct doca_comch_producer *producer, const struct doca_buf *buf, uint8_t *imm_data, uint32_t imm_data_len, uint32_t consumer_id, struct doca_comch_producer_task_send **task)
DOCA_STABLE doca_error_t doca_ctx_start(struct doca_ctx *ctx)
Finalizes all configurations, and starts the DOCA CTX.
DOCA_STABLE doca_error_t doca_ctx_get_state(const struct doca_ctx *ctx, enum doca_ctx_states *state)
Get context state.
DOCA_STABLE doca_error_t doca_ctx_set_user_data(struct doca_ctx *ctx, union doca_data user_data)
set user data to context
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_IDLE
Definition: doca_ctx.h:88
@ DOCA_CTX_STATE_RUNNING
Definition: doca_ctx.h:98
#define DOCA_DEVINFO_REP_PCI_ADDR_SIZE
Buffer size to hold PCI BDF format: "XXXX:XX:XX.X". Including a null terminator.
Definition: doca_dev.h:665
#define DOCA_DEVINFO_PCI_ADDR_SIZE
Buffer size to hold PCI BDF format: "XXXX:XX:XX.X". Including a null terminator.
Definition: doca_dev.h:313
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_descr(doca_error_t error)
Returns the description string of an error code.
@ DOCA_ERROR_INVALID_VALUE
Definition: doca_error.h:44
@ DOCA_ERROR_BAD_STATE
Definition: doca_error.h:56
@ DOCA_ERROR_AGAIN
Definition: doca_error.h:43
@ DOCA_SUCCESS
Definition: doca_error.h:38
@ DOCA_ERROR_NO_MEMORY
Definition: doca_error.h:45
@ DOCA_ERROR_IN_PROGRESS
Definition: doca_error.h:64
#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_mmap_set_memrange(struct doca_mmap *mmap, void *addr, size_t len)
Set the memory range of DOCA memory map.
DOCA_STABLE doca_error_t doca_mmap_destroy(struct doca_mmap *mmap)
Destroy DOCA Memory Map structure.
DOCA_STABLE doca_error_t doca_mmap_create(struct doca_mmap **mmap)
Allocates zero size memory map object with default/unset attributes.
DOCA_STABLE doca_error_t doca_mmap_set_permissions(struct doca_mmap *mmap, uint32_t access_mask)
Set access flags of the registered memory.
DOCA_STABLE doca_error_t doca_mmap_start(struct doca_mmap *mmap)
Start DOCA Memory Map.
DOCA_STABLE doca_error_t doca_mmap_add_dev(struct doca_mmap *mmap, struct doca_dev *dev)
Register DOCA memory map on a given device.
DOCA_STABLE doca_error_t doca_pe_destroy(struct doca_pe *pe)
Destroy doca progress engine.
DOCA_STABLE doca_error_t doca_pe_connect_ctx(struct doca_pe *pe, struct doca_ctx *ctx)
This method connects a context to a progress engine.
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 doca_error_t doca_pe_create(struct doca_pe **pe)
Creates DOCA progress engine.
DOCA_STABLE void doca_task_free(struct doca_task *task)
Free a task back to where it was allocated from.
@ DOCA_ACCESS_FLAG_PCI_READ_WRITE
Definition: doca_types.h:91
@ DOCA_ACCESS_FLAG_PCI_READ_ONLY
Definition: doca_types.h:87
const struct ip_frag_config * cfg
Definition: ip_frag_dp.c:0
void * aligned_alloc(size_t alignment, size_t size)
Definition: os_utils.cpp:126
static doca_error_t messages_number_callback(void *param, void *config)
void comch_recv_event_cb(struct doca_comch_event_msg_recv *event, uint8_t *recv_buffer, uint32_t msg_len, struct doca_comch_connection *comch_connection)
#define MAX_MSG_SIZE
static void send_task_fail_callback(struct doca_comch_producer_task_send *task, union doca_data task_user_data, union doca_data ctx_user_data)
static doca_error_t start_threads(struct cc_ctx *ctx, struct comch_cfg *comch_cfg)
#define CACHE_ALIGN
void expired_consumer_callback(struct doca_comch_event_consumer *event, struct doca_comch_connection *comch_connection, uint32_t id)
doca_error_t sc_start(struct comch_cfg *comch_cfg, struct sc_config *cfg, struct cc_ctx *ctx)
DOCA_LOG_REGISTER(SECURE_CHANNEL::Core)
static doca_error_t rep_pci_addr_callback(void *param, void *config)
static void * run_consumer(void *context)
static double calculate_timediff_ms(struct timespec *end, struct timespec *start)
#define CLOCK_TYPE_ID
static void * run_producer(void *context)
#define MAX_FASTPATH_TASKS
#define NS_PER_MSEC
static void recv_task_fail_callback(struct doca_comch_consumer_task_post_recv *task, union doca_data task_user_data, union doca_data ctx_user_data)
static void send_task_completed_callback(struct doca_comch_producer_task_send *task, union doca_data task_user_data, union doca_data ctx_user_data)
static void destroy_local_memory(struct local_memory_bufs *local_mem)
static void recv_task_completed_callback(struct doca_comch_consumer_task_post_recv *task, union doca_data task_user_data, union doca_data ctx_user_data)
void new_consumer_callback(struct doca_comch_event_consumer *event, struct doca_comch_connection *comch_connection, uint32_t id)
doca_error_t register_secure_channel_params(void)
static doca_error_t dev_pci_addr_callback(void *param, void *config)
static doca_error_t message_size_callback(void *param, void *config)
static doca_error_t prepare_local_memory(struct local_memory_bufs *local_mem, const char *pci_addr, size_t buf_len, uint32_t num_bufs, uint32_t permissions)
#define SLEEP_IN_NANOS
#define NS_PER_SEC
@ START_MSG
@ END_MSG
@ SC_MODE_DPU
@ FASTPATH_IN_PROGRESS
@ FASTPATH_COMPLETE
@ FASTPATH_ERROR
#define atomic_fetch_sub(object, operand)
Definition: stdatomic.h:153
#define atomic_init
Definition: stdatomic.h:61
#define atomic_load(object)
Definition: stdatomic.h:138
struct doca_comch_connection * comch_connection
struct timespec start_time
struct timespec end_time
enum transfer_state state
enum ip_frag_mode mode
Definition: ip_frag_dp.h:57
struct doca_dev * dev
struct doca_buf_inventory * inv
struct doca_mmap * mmap
enum msg_type type
Convenience type for representing opaque data.
Definition: doca_types.h:56
void * ptr
Definition: doca_types.h:57
struct upf_accel_ctx * ctx
size_t strlcpy(char *dst, const char *src, size_t size)
Definition: utils.c:123
noreturn doca_error_t sdk_version_callback(void *param, void *doca_config)
Definition: utils.c:41