### Compile and Execute DOCA Samples Source: https://context7.com/nvidia-doca/doca-samples/llms.txt This script demonstrates the standard workflow for building DOCA applications using Meson and Ninja, followed by examples of executing various samples like DMA copy, file compression, and SHA hashing. ```bash cd doca-samples/applications meson /tmp/build ninja -C /tmp/build /tmp/build/dma_copy/doca_dma_copy -p 03:00.0 -r 3b:00.0 -f /tmp/output.txt /tmp/build/dma_copy/doca_dma_copy -p 3b:00.0 -f /path/to/input.txt /tmp/build/file_compression/doca_file_compression -p 03:00.0 -f input.txt -o compressed.deflate /tmp/build/sha_create/doca_sha_create -p 03:00.0 -d "Hello DOCA!" /tmp/build/rdma_send_receive/doca_rdma_receive -d mlx5_0 ``` -------------------------------- ### Initialize and Configure DOCA Progress Engine Source: https://context7.com/nvidia-doca/doca-samples/llms.txt This snippet demonstrates how to create a Progress Engine instance, initialize a DMA context, and bind them together. It also configures task callbacks and starts the context to enable asynchronous processing. ```c #include #include #include #define NUM_TASKS 16 struct sample_state { struct doca_pe *pe; struct doca_dma *dma; struct doca_ctx *ctx; size_t num_completed_tasks; }; doca_error_t setup_progress_engine(struct sample_state *state, struct doca_dev *dev) { union doca_data ctx_user_data = {0}; doca_error_t result; result = doca_pe_create(&state->pe); if (result != DOCA_SUCCESS) return result; result = doca_dma_create(dev, &state->dma); if (result != DOCA_SUCCESS) { doca_pe_destroy(state->pe); return result; } state->ctx = doca_dma_as_ctx(state->dma); result = doca_pe_connect_ctx(state->pe, state->ctx); if (result != DOCA_SUCCESS) { doca_dma_destroy(state->dma); doca_pe_destroy(state->pe); return result; } ctx_user_data.ptr = state; doca_ctx_set_user_data(state->ctx, ctx_user_data); result = doca_dma_task_memcpy_set_conf(state->dma, dma_task_completed_callback, dma_task_error_callback, NUM_TASKS); if (result != DOCA_SUCCESS) { doca_dma_destroy(state->dma); doca_pe_destroy(state->pe); return result; } return doca_ctx_start(state->ctx); } ``` -------------------------------- ### GET /apsh/modules Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_apsh/README.md Retrieves the list of installed modules on a monitored system. ```APIDOC ## GET /apsh/modules ### Description Retrieves the list of all installed modules on the target system. ### Method GET ### Endpoint /apsh/modules ### Parameters #### Query Parameters - **vuid** (string) - Required - The VUID of the remote PCI device. ### Response #### Success Response (200) - **modules** (array) - List of installed modules. #### Response Example { "modules": [ { "name": "ntoskrnl.exe", "path": "C:\\Windows\\System32" } ] } ``` -------------------------------- ### DOCA Device Discovery and Initialization Source: https://context7.com/nvidia-doca/doca-samples/llms.txt Demonstrates how to discover and open NVIDIA BlueField DPUs using the DOCA device API. It includes examples for opening a device by PCI address with capability checks and opening a device based on supported capabilities. This is a fundamental step for any DOCA application. ```c #include #include #include /* Function to check if device supports DMA memcpy capability */ static doca_error_t check_dev_dma_capable(struct doca_devinfo *devinfo) { return doca_dma_cap_task_memcpy_is_supported(devinfo); } /* Open device by PCI address with capability check */ doca_error_t open_device_example(void) { struct doca_dev *dev = NULL; const char *pci_addr = "03:00.0"; /* BlueField PCI address */ doca_error_t result; /* Open device with specific PCI address and capability check */ result = open_doca_device_with_pci(pci_addr, check_dev_dma_capable, &dev); if (result != DOCA_SUCCESS) { DOCA_LOG_ERR("Failed to open device: %s", doca_error_get_descr(result)); return result; } DOCA_LOG_INFO("Successfully opened DOCA device at %s", pci_addr); /* Use device... */ /* Cleanup */ doca_dev_close(dev); return DOCA_SUCCESS; } /* Alternative: Open device with any supported capability */ doca_error_t open_device_with_capabilities(struct doca_dev **dev) { return open_doca_device_with_capabilities(check_dev_dma_capable, dev); } ``` -------------------------------- ### GET /apsh/libs Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_apsh/README.md Retrieves the list of loadable libraries for a specific process on a monitored system. ```APIDOC ## GET /apsh/libs ### Description Retrieves the list of loadable libraries for a specific process identified by PID. ### Method GET ### Endpoint /apsh/libs ### Parameters #### Query Parameters - **pid** (integer) - Required - The process ID to query. - **vuid** (string) - Required - The VUID of the remote PCI device. ### Response #### Success Response (200) - **libraries** (array) - List of library objects containing name and attributes. #### Response Example { "libraries": [ { "name": "kernel32.dll", "base_address": "0x7ff..." } ] } ``` -------------------------------- ### Build GPUNetIO Sample Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_gpunetio/README.md Compiles the GPUNetIO sample application using meson and ninja, ensuring DOCA and DPDK environment variables are configured. ```bash cd /opt/mellanox/doca/samples/doca_gpunetio/gpunetio_send_wait_time meson build ninja -C build ``` -------------------------------- ### GET /apsh/threads Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_apsh/README.md Retrieves the list of threads for a specific process. ```APIDOC ## GET /apsh/threads ### Description Retrieves the list of threads associated with a specific process PID. ### Method GET ### Endpoint /apsh/threads ### Parameters #### Query Parameters - **pid** (integer) - Required - The process ID. - **vuid** (string) - Required - The VUID of the remote PCI device. ### Response #### Success Response (200) - **threads** (array) - List of thread objects. #### Response Example { "threads": [ { "tid": 1, "state": "running" } ] } ``` -------------------------------- ### Build DOCA Management Data Direct Sample (Shell) Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_mgmt/README.md This snippet shows the commands to build the DOCA Management Data Direct sample using Meson. It navigates to the sample directory, sets up the build environment, and compiles the project. The resulting binary 'doca_mgmt_data_direct' is placed in the 'build' directory. ```shell cd /doca_mgmt/mgmt_data_direct meson setup build meson compile -C build ``` -------------------------------- ### GET /apsh/processes Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_apsh/README.md Retrieves the list of running processes on a monitored system. ```APIDOC ## GET /apsh/processes ### Description Retrieves the list of currently running processes on the target system. ### Method GET ### Endpoint /apsh/processes ### Parameters #### Query Parameters - **vuid** (string) - Required - The VUID of the remote PCI device. ### Response #### Success Response (200) - **processes** (array) - List of running processes with their attributes. #### Response Example { "processes": [ { "pid": 1234, "name": "explorer.exe" } ] } ``` -------------------------------- ### GET /apsh/envars Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_apsh/README.md Retrieves the environment variables for a specific process on Windows systems. ```APIDOC ## GET /apsh/envars ### Description Retrieves the environment variables for a specific process (Windows only). ### Method GET ### Endpoint /apsh/envars ### Parameters #### Query Parameters - **pid** (integer) - Required - The process ID. - **vuid** (string) - Required - The VUID of the remote PCI device. ### Response #### Success Response (200) - **envars** (object) - Key-value pairs of environment variables. #### Response Example { "envars": { "PATH": "C:\\Windows", "TEMP": "C:\\Temp" } } ``` -------------------------------- ### GET /apsh/vads Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_apsh/README.md Retrieves the list of virtual address descriptors (VADs) for a process. ```APIDOC ## GET /apsh/vads ### Description Retrieves the list of virtual address descriptors for a specific process. ### Method GET ### Endpoint /apsh/vads ### Parameters #### Query Parameters - **pid** (integer) - Required - The process ID. - **vuid** (string) - Required - The VUID of the remote PCI device. ### Response #### Success Response (200) - **vads** (array) - List of VAD objects. #### Response Example { "vads": [ { "start": "0x0", "end": "0x1000", "protection": "read-only" } ] } ``` -------------------------------- ### Implement DOCA COMCH Client Communication Source: https://context7.com/nvidia-doca/doca-samples/llms.txt This snippet demonstrates how to initialize a DOCA COMCH client, set up event callbacks for message reception and state changes, and perform message transmission. It requires a valid DOCA device and Progress Engine instance to manage the asynchronous communication lifecycle. ```c #include #include #define SLEEP_IN_NANOS (10 * 1000) struct comch_client_state { struct doca_dev *dev; struct doca_pe *pe; struct doca_comch_client *client; bool finished; doca_error_t result; }; static void send_completed_callback(struct doca_comch_task_send *task, union doca_data task_user_data, union doca_data ctx_user_data) { struct comch_client_state *state = (struct comch_client_state *)ctx_user_data.ptr; state->result = DOCA_SUCCESS; DOCA_LOG_INFO("Message sent successfully"); doca_task_free(doca_comch_task_send_as_task(task)); } static void message_recv_callback(struct doca_comch_event_msg_recv *event, uint8_t *recv_buffer, uint32_t msg_len, struct doca_comch_connection *connection) { union doca_data user_data = doca_comch_connection_get_user_data(connection); struct comch_client_state *state = (struct comch_client_state *)user_data.ptr; DOCA_LOG_INFO("Received message: '%.*s'", (int)msg_len, recv_buffer); doca_ctx_stop(doca_comch_client_as_ctx(state->client)); } static void 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) { struct comch_client_state *state = (struct comch_client_state *)user_data.ptr; switch (next_state) { case DOCA_CTX_STATE_IDLE: DOCA_LOG_INFO("Client stopped"); state->finished = true; break; case DOCA_CTX_STATE_RUNNING: DOCA_LOG_INFO("Connected to server, sending message"); break; default: break; } } doca_error_t comch_client_send_message(const char *server_name, const char *pci_addr, const char *message) { struct comch_client_state state = {0}; struct doca_comch_task_send *send_task; struct doca_comch_connection *connection; union doca_data ctx_user_data = {0}; struct timespec ts = {.tv_sec = 0, .tv_nsec = SLEEP_IN_NANOS}; doca_error_t result; result = open_doca_device_with_pci(pci_addr, NULL, &state.dev); if (result != DOCA_SUCCESS) return result; result = doca_pe_create(&state.pe); if (result != DOCA_SUCCESS) goto close_dev; result = doca_comch_client_create(state.dev, server_name, &state.client); if (result != DOCA_SUCCESS) goto destroy_pe; doca_pe_connect_ctx(state.pe, doca_comch_client_as_ctx(state.client)); ctx_user_data.ptr = &state; doca_ctx_set_user_data(doca_comch_client_as_ctx(state.client), ctx_user_data); doca_ctx_set_state_changed_cb(doca_comch_client_as_ctx(state.client), client_state_changed_callback); doca_comch_client_task_send_set_conf(state.client, send_completed_callback, NULL, 1); doca_comch_client_event_msg_recv_register(state.client, message_recv_callback); result = doca_ctx_start(doca_comch_client_as_ctx(state.client)); if (result != DOCA_SUCCESS) goto destroy_client; while (!state.finished) { if (doca_pe_progress(state.pe) == 0) nanosleep(&ts, &ts); } result = state.result; destroy_client: doca_comch_client_destroy(state.client); destroy_pe: doca_pe_destroy(state.pe); close_dev: doca_dev_close(state.dev); return result; } ``` -------------------------------- ### Perform RDMA Data Send with DOCA Source: https://context7.com/nvidia-doca/doca-samples/llms.txt This C code demonstrates how to initialize an RDMA context, configure memory mapping, and submit an asynchronous send task. It requires a valid DOCA device, buffer inventory management, and an out-of-band connection exchange with a remote peer. ```c #include #include #define DEFAULT_STRING "Hi DOCA RDMA!" #define MEM_RANGE_LEN 4096 struct rdma_resources { struct doca_dev *dev; struct doca_pe *pe; struct doca_mmap *mmap; struct doca_buf_inventory *buf_inv; struct doca_rdma *rdma; struct doca_ctx *rdma_ctx; struct doca_buf *buf; char *buffer; }; static doca_error_t check_rdma_send_capable(const struct doca_devinfo *devinfo) { return doca_rdma_cap_task_send_is_supported(devinfo); } doca_error_t rdma_send_example(const char *device_name, const char *message) { struct rdma_resources resources = {0}; struct doca_rdma_task_send *send_task; union doca_data task_user_data = {0}; doca_error_t result, task_result; struct timespec ts = {.tv_sec = 0, .tv_nsec = 10000}; size_t msg_len = strlen(message); result = open_doca_device_with_ibdev_name((const uint8_t *)device_name, strlen(device_name), check_rdma_send_capable, &resources.dev); if (result != DOCA_SUCCESS) return result; result = doca_rdma_create(resources.dev, &resources.rdma); if (result != DOCA_SUCCESS) goto close_dev; resources.rdma_ctx = doca_rdma_as_ctx(resources.rdma); result = doca_rdma_set_permissions(resources.rdma, DOCA_ACCESS_FLAG_LOCAL_READ_WRITE); if (result != DOCA_SUCCESS) goto destroy_rdma; doca_pe_create(&resources.pe); doca_pe_connect_ctx(resources.pe, resources.rdma_ctx); doca_rdma_task_send_set_conf(resources.rdma, send_task_completion_cb, send_task_error_cb, 1); resources.buffer = malloc(MEM_RANGE_LEN); memcpy(resources.buffer, message, msg_len); doca_mmap_create(&resources.mmap); doca_mmap_add_dev(resources.mmap, resources.dev); doca_mmap_set_permissions(resources.mmap, DOCA_ACCESS_FLAG_LOCAL_READ_ONLY); doca_mmap_set_memrange(resources.mmap, resources.buffer, MEM_RANGE_LEN); doca_mmap_start(resources.mmap); doca_buf_inventory_create(1, &resources.buf_inv); doca_buf_inventory_start(resources.buf_inv); doca_buf_inventory_buf_get_by_data(resources.buf_inv, resources.mmap, resources.buffer, msg_len, &resources.buf); doca_ctx_start(resources.rdma_ctx); const void *conn_desc; size_t conn_desc_size; doca_rdma_export(resources.rdma, &conn_desc, &conn_desc_size); task_user_data.ptr = &task_result; result = doca_rdma_task_send_alloc_init(resources.rdma, resources.buf, task_user_data, &send_task); if (result != DOCA_SUCCESS) goto cleanup; result = doca_task_submit(doca_rdma_task_send_as_task(send_task)); bool running = true; while (running) { if (doca_pe_progress(resources.pe) == 0) nanosleep(&ts, &ts); } DOCA_LOG_INFO("RDMA send completed: %s", message); result = task_result; cleanup: doca_buf_dec_refcount(resources.buf, NULL); free(resources.buffer); doca_mmap_destroy(resources.mmap); destroy_rdma: doca_rdma_destroy(resources.rdma); close_dev: doca_dev_close(resources.dev); return result; } ``` -------------------------------- ### Manage DOCA Data Direct via CLI Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_mgmt/README.md Commands to get or set the Data Direct state for Virtual Functions (VF) or Scalable Functions (SF) using the doca_mgmt_data_direct utility. ```bash # Get state for a VF doca_mgmt_data_direct get --vf-pci-addr 0000:08:00.2 # Enable data direct for a VF doca_mgmt_data_direct set --vf-pci-addr 0000:08:00.2 --enabled true # Disable data direct for a VF doca_mgmt_data_direct set --vf-pci-addr 0000:08:00.2 --enabled false # Enable for specific VF representor doca_mgmt_data_direct set --rep pci/0000:08:00.0,pf0vf0 --enabled true # Enable for specific SF representor doca_mgmt_data_direct set --rep pci/0000:08:00.0,pf0sf88 --enabled true ``` -------------------------------- ### Build DOCA Flow CT Samples Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_flow/README.md Commands to compile the DOCA Flow CT UDP sample using the meson build system and ninja. The resulting binary is generated in the specified build directory. ```bash cd doca_flow/flow_ct_udp meson /tmp/build ninja -C /tmp/build ``` -------------------------------- ### Execute DOCA Flow CT Sample Source: https://github.com/nvidia-doca/doca-samples/blob/master/samples/doca_flow/README.md Standard command-line syntax for running DOCA samples. It supports standard DOCA flags for logging and configuration, as well as program-specific flags like device address. ```bash Usage: doca_ [DOCA Flags] [Program Flags] /tmp/build/samples/ -h ``` -------------------------------- ### Initialize DOCA Flow Source: https://context7.com/nvidia-doca/doca-samples/llms.txt Initializes the DOCA Flow library with specified queue count and operation mode. It sets up the configuration, including the callback for entry processing. Dependencies include \"doca_flow.h\" and \"doca_dev.h\". ```c #include #include #define DEFAULT_TIMEOUT_US 10000 /* Entry status tracking */ struct entries_status { bool failure; int nb_processed; }; /* Entry processing callback */ void check_for_valid_entry(struct doca_flow_pipe_entry *entry, uint16_t pipe_queue, enum doca_flow_entry_status status, enum doca_flow_entry_op op, void *user_ctx) { struct entries_status *es = (struct entries_status *)user_ctx; if (status != DOCA_FLOW_ENTRY_STATUS_SUCCESS) { DOCA_LOG_ERR("Entry processing failed"); es->failure = true; } es->nb_processed++; } doca_error_t init_doca_flow(int nb_queues, const char *mode) { struct doca_flow_cfg *cfg; doca_error_t result; /* Create flow configuration */ result = doca_flow_cfg_create(&cfg); if (result != DOCA_SUCCESS) return result; /* Set queue count */ result = doca_flow_cfg_set_nr_queues(cfg, nb_queues); if (result != DOCA_SUCCESS) goto destroy_cfg; /* Set operation mode (vnf, switch, remote_vnf) */ result = doca_flow_cfg_set_mode_args(cfg, mode); if (result != DOCA_SUCCESS) goto destroy_cfg; /* Set entry callback */ result = doca_flow_cfg_set_cb_entry_process(cfg, check_for_valid_entry); if (result != DOCA_SUCCESS) goto destroy_cfg; /* Initialize DOCA Flow */ result = doca_flow_init(cfg); if (result != DOCA_SUCCESS) DOCA_LOG_ERR("Failed to init DOCA Flow: %s", doca_error_get_descr(result)); destroy_cfg: doca_flow_cfg_destroy(cfg); return result; } ``` -------------------------------- ### Encrypt Data with DOCA AES-GCM in C Source: https://context7.com/nvidia-doca/doca-samples/llms.txt This C function demonstrates how to encrypt plaintext data using the DOCA AES-GCM library. It handles device opening, context creation, key setup, and task submission for encryption. The function requires a PCI address, plaintext data, output file path, encryption key, and IV. It returns a doca_error_t status. ```c #include #include #include #include doca_error_t aes_gcm_encrypt_file(const char *pci_addr, char *plaintext, size_t plaintext_len, const char *output_path, uint8_t *key, size_t key_len, uint8_t *iv, size_t iv_len) { struct doca_dev *dev = NULL; struct doca_aes_gcm *aes_gcm = NULL; struct doca_aes_gcm_key *doca_key = NULL; struct doca_pe *pe = NULL; struct doca_buf *src_buf = NULL, *dst_buf = NULL; char *ciphertext = NULL; uint64_t max_buf_size; doca_error_t result; FILE *out_file; /* Open device */ result = open_doca_device_with_pci(pci_addr, NULL, &dev); if (result != DOCA_SUCCESS) return result; /* Query max buffer size */ result = doca_aes_gcm_cap_task_encrypt_get_max_buf_size( doca_dev_as_devinfo(dev), &max_buf_size); if (result != DOCA_SUCCESS || plaintext_len > max_buf_size) { doca_dev_close(dev); return DOCA_ERROR_INVALID_VALUE; } /* Create AES-GCM context */ result = doca_aes_gcm_create(dev, &aes_gcm); if (result != DOCA_SUCCESS) goto close_dev; /* Create PE and connect */ doca_pe_create(&pe); doca_pe_connect_ctx(pe, doca_aes_gcm_as_ctx(aes_gcm)); /* Start context */ doca_ctx_start(doca_aes_gcm_as_ctx(aes_gcm)); /* Allocate ciphertext buffer (plaintext + tag) */ ciphertext = calloc(1, max_buf_size); /* Setup mmaps and buffers (similar to previous examples) */ /* ... */ /* Create AES-GCM key - determine key type based on length */ enum doca_aes_gcm_key_type key_type; switch (key_len) { case 16: key_type = DOCA_AES_GCM_KEY_128; break; case 24: key_type = DOCA_AES_GCM_KEY_192; break; case 32: key_type = DOCA_AES_GCM_KEY_256; break; default: result = DOCA_ERROR_INVALID_VALUE; goto cleanup; } result = doca_aes_gcm_key_create(aes_gcm, key, key_type, &doca_key); if (result != DOCA_SUCCESS) goto cleanup; /* Submit encrypt task with IV, tag size, AAD */ uint32_t tag_size = 16; /* 128-bit authentication tag */ uint32_t aad_size = 0; /* No additional authenticated data */ /* result = submit_aes_gcm_encrypt_task(...) */ /* Poll for completion... */ /* Get encrypted data and write to file */ size_t ciphertext_len; doca_buf_get_data_len(dst_buf, &ciphertext_len); out_file = fopen(output_path, "wb"); fwrite(ciphertext, 1, ciphertext_len, out_file); fclose(out_file); DOCA_LOG_INFO("Encrypted %zu bytes, output: %zu bytes (includes %u-byte tag)", plaintext_len, ciphertext_len, tag_size); cleanup: if (doca_key) doca_aes_gcm_key_destroy(doca_key); free(ciphertext); doca_aes_gcm_destroy(aes_gcm); close_dev: doca_dev_close(dev); return result; } ```