NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
pe_task_error_sample.c File Reference
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <doca_mmap.h>
#include <doca_buf.h>
#include <doca_buf_inventory.h>
#include <doca_ctx.h>
#include <doca_dma.h>
#include <doca_types.h>
#include <doca_log.h>
#include <doca_pe.h>
#include <samples/common.h>
#include "pe_common.h"
Include dependency graph for pe_task_error_sample.c:

Go to the source code of this file.

Data Structures

struct  pe_task_error_sample_state
 

Macros

#define EXIT_ON_FAILURE(_expression_)
 
#define NUM_TASKS   (255)
 
#define DMA_BUFFER_SIZE   (1024)
 
#define BUFFER_SIZE   (DMA_BUFFER_SIZE * 2 * NUM_TASKS)
 
#define BUF_INVENTORY_SIZE   (NUM_TASKS * 2)
 

Functions

 DOCA_LOG_REGISTER (PE_TASK_ERROR::SAMPLE)
 
static const char * ctx_state_to_string (enum doca_ctx_states state)
 
static void dma_state_changed_cb (const union doca_data ctx_user_data, struct doca_ctx *ctx, enum doca_ctx_states prev_state, enum doca_ctx_states next_state)
 
static void dma_memcpy_completed_callback (struct doca_dma_task_memcpy *dma_task, union doca_data task_user_data, union doca_data ctx_user_data)
 
static void dma_memcpy_error_callback (struct doca_dma_task_memcpy *dma_task, union doca_data task_user_data, union doca_data ctx_user_data)
 
static doca_error_t create_dma (struct pe_task_error_sample_state *state)
 
static doca_error_t allocate_tasks (struct pe_sample_state_base *state, struct doca_dma *dma, uint32_t num_tasks, size_t dma_buffer_size, struct doca_dma_task_memcpy **tasks)
 
doca_error_t poll_for_dma_stop (struct pe_task_error_sample_state *state)
 
static void cleanup (struct pe_task_error_sample_state *state)
 
static doca_error_t run (struct pe_task_error_sample_state *state)
 
doca_error_t run_pe_task_error_sample (void)
 

Macro Definition Documentation

◆ BUF_INVENTORY_SIZE

#define BUF_INVENTORY_SIZE   (NUM_TASKS * 2)

Definition at line 71 of file pe_task_error_sample.c.

◆ BUFFER_SIZE

#define BUFFER_SIZE   (DMA_BUFFER_SIZE * 2 * NUM_TASKS)

Definition at line 70 of file pe_task_error_sample.c.

◆ DMA_BUFFER_SIZE

#define DMA_BUFFER_SIZE   (1024)

Definition at line 69 of file pe_task_error_sample.c.

◆ EXIT_ON_FAILURE

#define EXIT_ON_FAILURE (   _expression_)
Value:
{ \
doca_error_t _status_ = _expression_; \
if (_status_ != DOCA_SUCCESS) { \
DOCA_LOG_ERR("%s failed with status %s", __func__, doca_error_get_descr(_status_)); \
return _status_; \
} \
}
if(bitoffset % 64+bitlength > 64) result|
DOCA_STABLE const char * doca_error_get_descr(doca_error_t error)
Returns the description string of an error code.
@ DOCA_SUCCESS
Definition: doca_error.h:38

This sample demonstrates how to handle task error The sample submits a couple of good tasks and then submits a bad task that will fail in the HW. The sample does not use doca_task_try_submit to avoid submission failure. The sample uses DOCA_DMA context as an example (DOCA PE can run any library that abides to the PE context API). The sample runs 255 DMA memcpy tasks, failing the second task. Due to the asynchronous nature of the HW some tasks that are submitted after the faulty task are completed before it with success. This macro is used to minimize code size. The macro runs an expression and returns error if the expression status is not DOCA_SUCCESS

Definition at line 58 of file pe_task_error_sample.c.

◆ NUM_TASKS

#define NUM_TASKS   (255)

Definition at line 68 of file pe_task_error_sample.c.

Function Documentation

◆ allocate_tasks()

static doca_error_t allocate_tasks ( struct pe_sample_state_base state,
struct doca_dma *  dma,
uint32_t  num_tasks,
size_t  dma_buffer_size,
struct doca_dma_task_memcpy **  tasks 
)
static

This method allocate the DMA tasks but does not submit them. This is a sample choice. A task can be submitted immediately after it is allocated. The method allocates a bad task after a couple of good tasks and then allocates good tasks as well. DMA will move to stopping state once the task completes as error. From that moment all tasks will be completed with error.

@state [in]: sample state @dma [in]: DMA context to allocate the tasks from @num_tasks [in]: Number of tasks per group @dma_buffer_size [in]: Size of DMA buffer @tasks [in]: tasks to allocate

Returns
: DOCA_SUCCESS on success and DOCA_ERROR otherwise

Definition at line 256 of file pe_task_error_sample.c.

◆ cleanup()

static void cleanup ( struct pe_task_error_sample_state state)
static

This method cleans up the sample resources in reverse order of their creation. This method does not check for destroy return values for simplify. Real code should check the return value and act accordingly (e.g. if doca_ctx_stop failed with DOCA_ERROR_IN_PROGRESS it means that some contexts are still added or even that there are still in flight tasks in the progress engine).

@state [in]: sample state

Definition at line 340 of file pe_task_error_sample.c.

◆ create_dma()

static doca_error_t create_dma ( struct pe_task_error_sample_state state)
static

Create DMA

@state [in]: sample state

Returns
: DOCA_SUCCESS on success and DOCA_ERROR otherwise

The ctx user data is received in the task completion callback. Setting the state to the user data binds the program to the callback. See dma_memcpy_completed_callback for usage.

Definition at line 212 of file pe_task_error_sample.c.

◆ ctx_state_to_string()

static const char* ctx_state_to_string ( enum doca_ctx_states  state)
static

Convert doca_ctx_states to string

@state [in]: context state

Returns
: string representation of the state

Definition at line 92 of file pe_task_error_sample.c.

◆ dma_memcpy_completed_callback()

static void dma_memcpy_completed_callback ( struct doca_dma_task_memcpy *  dma_task,
union doca_data  task_user_data,
union doca_data  ctx_user_data 
)
static

process_completed_dma_memcpy_task returns doca_error_t to be able to use EXIT_ON_FAILURE, but there is nothing to do with the return value.

Definition at line 152 of file pe_task_error_sample.c.

◆ dma_memcpy_error_callback()

static void dma_memcpy_error_callback ( struct doca_dma_task_memcpy *  dma_task,
union doca_data  task_user_data,
union doca_data  ctx_user_data 
)
static

The task is no longer required, therefore it can be freed. Freeing the task in the error callback facilitates automatic stop of the library in case of an error. If the task is not freed here then all tasks should be freed before final call to doca_pe_progress. The context won't stop until all tasks are freed.

Definition at line 180 of file pe_task_error_sample.c.

◆ dma_state_changed_cb()

static void dma_state_changed_cb ( const union doca_data  ctx_user_data,
struct doca_ctx *  ctx,
enum doca_ctx_states  prev_state,
enum doca_ctx_states  next_state 
)
static

DMA state changed callback

@ctx_user_data [in]: ctx user data @ctx [in]: ctx @prev_state [in]: previous ctx state @next_state [in]: next ctx state

idle -> starting state is irrelevant because DMA start is synchronous. idle -> running is obvious so this callback shall ignore it. running -> stopping is expected because the sample shall request to stop after half of the tasks are done. stopping -> stopped is expected (implies that all in-flight tasks are flushed). The program can use this callback to raise a flag that breaks the progress loop or any other action that depends on state transition

Definition at line 116 of file pe_task_error_sample.c.

◆ DOCA_LOG_REGISTER()

DOCA_LOG_REGISTER ( PE_TASK_ERROR::SAMPLE  )

◆ poll_for_dma_stop()

doca_error_t poll_for_dma_stop ( struct pe_task_error_sample_state state)

This method polls the PE until DMA is stopped. The DMA stop is asynchronous in this sample so after all tasks are completed the PE must be called once again to move the DMA from stopping to idle.

@state [in]: sample state

Returns
: DOCA_SUCCESS on success and DOCA_ERROR otherwise

Notice that the context will remain in stopping state until all tasks are freed. This sample frees the tasks in the completion or error callback. But if the developer chooses to free the tasks outside of these callbacks then they have to be freed before this loop.

Definition at line 311 of file pe_task_error_sample.c.

◆ run()

static doca_error_t run ( struct pe_task_error_sample_state state)
static

Run the sample The method (and the method it calls) does not cleanup anything in case of failures. It assumes that cleanup is called after it at any case.

@state [in]: sample state

Returns
: DOCA_SUCCESS on success and DOCA_ERROR otherwise

Definition at line 361 of file pe_task_error_sample.c.

◆ run_pe_task_error_sample()

doca_error_t run_pe_task_error_sample ( void  )

Run the PE polling sample

Returns
: DOCA_SUCCESS on success and DOCA_ERROR otherwise

Definition at line 388 of file pe_task_error_sample.c.