Doca Common
NVIDIAOfficialCreated by NVIDIA
- Skill
- Tool integration
- Software development
- Apache-2.0
- Medium risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The doca-common skill serves as the essential foundation for all DOCA-based development. It covers the core primitives required before interacting with higher-level libraries like Flow, RDMA, or Ethernet. This includes managing the doca_ctx lifecycle, discovering hardware via doca_dev and doca_devinfo, implementing zero-copy I/O with doca_buf and doca_mmap, driving the progress engine (doca_pe), and configuring the two-tier logging system. It is designed to be loaded alongside per-library skills to provide the underlying context and structural requirements for any DOCA application.
What it does
- Guides the initialization and lifecycle management of doca_ctx and doca_dev.
- Explains the wiring of doca_buf, doca_mmap, and doca_buf_inventory for zero-copy I/O.
- Provides patterns for driving the doca_pe progress engine to ensure task completion.
- Clarifies the two-tier DOCA logging model for effective application debugging.
- Assists in capability discovery using doca_devinfo and doca_*_cap_* functions.
- Helps interpret common DOCA_ERROR_* codes encountered during application startup.
When to use it
- When setting up the initial skeleton for a new DOCA application.
- When debugging task submission issues where tasks are submitted but never complete.
- When needing to share buffers across different DOCA libraries.
- When troubleshooting initialization errors like DOCA_ERROR_BAD_STATE.
- When configuring logging levels to capture application-specific debug output.
- When verifying hardware capabilities before executing library-specific features.
Advantages
- Ensures a consistent and correct foundation for all DOCA library interactions.
- Reduces debugging time by addressing lifecycle and primitive-level issues first.
- Provides a unified approach to zero-copy buffer management across libraries.
- Standardizes the integration of the progress engine and logging across projects.
Usage examples
- “My DOCA RDMA tasks are submitted but nothing completes. What am I missing?”
- The agent will guide you through the doca_pe (progress engine) connection and the required run-loop pattern to ensure tasks are drained correctly.
- “I am getting a DOCA_ERROR_BAD_STATE from doca_ctx_start. How do I fix this?”
- The agent will help you verify the lifecycle order of your context initialization and ensure all required dependencies are configured before starting.
- “How do I share a buffer between doca_dma and doca_rdma?”
- The agent will explain the wiring of doca_mmap and doca_buf_inventory to create a shared buffer surface that both libraries can reference.
- “My DOCA_LOG_DBG lines are not appearing even with --sdk-log-level 60.”
- The agent will explain the two-tier logging model and how to correctly register your application-side log levels.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/nvidia/doca-common/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip doca-common.zip -d .agents/skills
Documentation by NVIDIA
DOCA Common
Examples
"Tasks submit but nothing completes." — start at the progress engine and ctx lifecycle, not a per-library rewrite.
"DOCA_ERROR_BAD_STATE from doca_ctx_start." — walk the Common lifecycle order before blaming Flow or RDMA.
Instructions
Follow Loading order below. Open the tasks companion for configure / build / run. Open the capabilities companion for ctx / buf / pe / log. Do not open every companion file.
Where to start: This skill is the foundation every DOCA app
loads first — before doca-flow, doca-rdma, doca-eth, doca-comch, or
any other higher-level library. Every doca_<library>_* context is
built on top of doca_ctx, every device handle is a doca_dev
discovered through doca_devinfo, every zero-copy buffer is a
doca_buf from a doca_buf_inventory over a doca_mmap, every
task completion drains through a doca_pe, and every log line emits
through doca_log. Open the capabilities companion when
the question is what does Common express on this install; open
the tasks companion when the user wants to do something
(configure / build / modify / run / test / debug). If the user has
not installed DOCA yet, route to
doca-setup/SKILL.md first. If the user is
already past the foundation and asking a library-specific question
(e.g. "how do I program a Flow pipe"), load the matching per-library
skill alongside this one — they cross-link back here for the shared
primitives.
Example questions this skill answers well
The CLASSES of doca-common questions this skill is built to answer, each with one worked example. The agent should treat the class as the load-bearing piece — the worked example is a single instance.
"What is the doca-common foundation I have to set up BEFORE I open a doca-flow / doca-rdma / doca-eth / … context?" — worked example: "I'm starting a brand-new DOCA Flow program on BlueField-3; what's the doca-common skeleton I need before I open the Flow port?". Answered by the universal foundation walk in
configure +
ctx +
dev +
progress engine.
"How do I discover a device and gate on its capabilities before trusting the public docs?" — worked example: "I want to use
doca_eth_txqbut the docs hint at a feature only on certain firmware bands". Answered by the capability-discovery rule (doca_devinfo_create_list→doca_*_cap_*against the activedoca_devinfois the runtime authority) indev +
use.
"What's the doca_buf / doca_mmap / doca_buf_inventory wiring for zero-copy I/O, and what's the lifecycle order?" — worked example: "I want to register a user-space buffer with my device, carve it into N data-plane buffers, and reference-count them across multiple DOCA libraries". Answered by the zero-copy buffer model in
buf +
the buffer-lifecycle walk in
configure +
use.
"How does the progress engine work and where do I have to call it?" — worked example: "my doca_rdma task submits cleanly but nothing completes — what loop am I missing?". Answered by the PE surface in
progress engine
the run-loop pattern in ## run.
"Why don't my DOCA log lines appear at the level I expect, and what's the difference between
--sdk-log-leveland the app-side setter?" — worked example: "I set--sdk-log-level 60(DEBUG), my ownDOCA_LOG_DBGlines still don't print". Answered by the two-tier log model in ## logthe tier-flip iteration in ## log.
"What does this
DOCA_ERROR_*from adoca_buf_*/doca_ctx_*/doca_dev_*/doca_pe_*/doca_log_*call mean?" — worked example: "DOCA_ERROR_BAD_STATEfromdoca_ctx_start". Answered by the Common overlay on the cross-libraryDOCA_ERROR_*taxonomy inError taxonomy
the layered ladder in
debug that escalates to
doca-debug/SKILL.md.
Audience
This skill serves every external developer building applications
that consume any DOCA library — i.e., users whose code calls any
doca_* symbol (directly in C/C++, or through FFI/bindings from
another language). Whether the user's primary library is doca-flow,
doca-rdma, doca-eth, doca-comch, doca-dma, doca-rmax, doca-sha,
doca-aes-gcm, doca-erasure-coding, or any other, the doca-common
surface is under it and the user will hit doca_buf, doca_ctx,
doca_dev, doca_pe, and doca_log as part of the first-app
journey. It is not for NVIDIA developers contributing to DOCA
Common itself.
Language scope
DOCA Common ships as a C library with pkg-config module name
doca-common. The shipped samples that demonstrate Common primitives
live inside every per-library samples tree (any
/opt/mellanox/doca/samples/<library>/<sample>/*_main.c is a worked
example of the universal foundation — doca_devinfo_create_list
→ doca_dev_open → per-library doca_ctx create → doca_pe_create
→ doca_pe_connect_ctx → doca_ctx_start → submit work → drive
doca_pe_progress → drain completions → doca_ctx_stop → destroy).
C and C++ consumers are the canonical case and the worked examples
in the tasks companion assume that path. Other-language consumers (Rust, Go,
Python, …) consume the same *.so through FFI or language-specific
bindings; the skill's contribution in that case is to keep the
universal foundation walk, the lifecycle, the capability-discovery
rule, the PE-drives-completion rule, and the two-tier log model
language-neutral, and to route the agent to the public C ABI as the
authoritative surface that any wrapper will eventually call.
When to load this skill
Load this skill whenever the user is doing any hands-on DOCA work — it is the foundation. Concretely:
Setting up the universal DOCA-side skeleton before opening any per-library context (Flow, RDMA, Eth, Comch, DMA, Rmax, …).
Discovering devices and representors and gating capability use on the active
doca_devinfovia thedoca_*_cap_*family.Wiring
doca_mmap+doca_buf_inventory+doca_buffor zero-copy I/O that crosses libraries (e.g. doca-eth feeds doca-dma feeds doca-rdma — they share the same buf surface).Driving the progress engine (
doca_pe_create/doca_pe_connect_ctx/doca_pe_progress) — the universal task-completion drain every DOCA Core context relies on.Wiring DOCA Log into a fresh app or modifying a shipped sample to add the user's own per-component log lines via the two-tier (
--sdk-log-levelvs app-side registry) model.Debugging a
DOCA_ERROR_*returned from anydoca_buf_*/doca_ctx_*/doca_dev_*/doca_pe_*/doca_log_*call — the Common surface is where most lifecycle / capability / permission errors first surface for higher-level libraries.Designing or extending non-C bindings (Rust, Go, Python, …) that wrap any DOCA library — for the universal foundation surface (buf, ctx, dev, pe, log) the wrapper has to expose first.
Do not load this skill for library-specific Flow, RDMA, Eth,
Comch, DMA, Rmax, … questions in isolation — load the matching
per-library skill alongside this one. Do not load this skill for
general DOCA orientation, install of DOCA itself, or
"where do I find docs". For those, use
doca-public-knowledge-map/SKILL.md
or doca-setup/SKILL.md.
What this skill provides
This is a thin loader. The body keeps only the orientation needed to pick the right next file. The substantive Common material lives in two companion files:
the capabilities companion — what doca-common expresses on this install: the
## Capabilities and modesoverview of the universal primitives every DOCA application touches; the five subsystem H2s (## log,## buf,## ctx,## dev,## progress engine) that own the per-primitive surface; the## Version compatibilitydoca-common-specific overlay; the## Error taxonomyCommon-side view of the universalDOCA_ERROR_*set; the## Observabilitysurface (logs, PE events, capability snapshots); and the## Safety policyoverlay on the bundle-wide hardware-safety meta-policy.the tasks companion — step-by-step workflows for the universal verbs (
configure,build,modify,run,test,debug,use) PLUS a## logverb-side that covers the two-tier log model in workflow form. Plus aDeferred task verbsblock that points install / deploy / rollback questions at the right next skill.
The skill assumes a host or BlueField where DOCA is already
installed at the standard location and the user has the privileges
their public install profile expects. It does not cover installing
DOCA — that path goes through
doca-setup/SKILL.md.
What this skill deliberately does not ship
This skill is agent guidance, not a samples or templates bundle. To keep the boundary clean, it deliberately does not contain — and pull requests should not add:
Pre-written DOCA application source code, in any language. The verified Common usage shows up inside every shipped DOCA sample at
/opt/mellanox/doca/samples/<library>/<sample>/*_main.cand inside every shipped reference application. The agent's job is to route the user to those files and prescribe a minimum-diff modification on them via the universal modify-a-sample workflow indoca-programming-guide/SKILL.md.Standalone build manifests (
meson.build,CMakeLists.txt,Cargo.toml,setup.py,go.mod, …) parked inside the skill. The agent constructs the build manifest in the user's project directory against the user's installed DOCA, wherepkg-config --modversion doca-commonis the source of truth.A
samples/,bindings/, orreference/subtree of any kind. A mock or incomplete artifact in this skill's tree, even one labeled "reference", is misleading: users will read it as buildable.
Loading order
Read this skill first to confirm the user's question is in scope.
For the universal primitives (
log/buf/ctx/dev/progress engine), thepkg-config --modversion doca-commonanchor, the Common error overlay, observability, and safety policy, see the capabilities companion.For step-by-step workflows — configure, build, modify, run, test, debug, use, log — see the tasks companion.
Both companion files cross-link to each other,
doca-version/SKILL.md for the canonical
version-handling rules,
doca-programming-guide/SKILL.md
for the universal modify-a-shipped-sample workflow and the
cross-library DOCA_ERROR_* taxonomy,
doca-debug/SKILL.md for the cross-cutting
debug ladder, and
doca-public-knowledge-map/SKILL.md
whenever the right answer is "look it up in the public docs or the
installed package layout" rather than "Common-specific guidance".
Related skills
doca-public-knowledge-map/SKILL.md— the routing table for every public DOCA documentation source and the on-disk layout of an installed DOCA package. Always available alongside this skill; this skill expects to be able to defer documentation-finding and install-layout questions there instead of duplicating them.doca-setup/SKILL.md— env preparation, install verification, and the I have no install yet path with the public NGC DOCA container (nvcr.io/nvidia/doca/doca) as the universal Stage-1 fallback. This skill assumes its preconditions are satisfied.doca-version/SKILL.md— canonical DOCA version-handling rules (four-way match, NGC semantics, headers-win-over-docs).pkg-config --modversion doca-commonis the build-time anchor every DOCA install carries; this skill's## Version compatibilityoverlays the Common-specific notes on top.doca-programming-guide/SKILL.md— general DOCA programming patterns shared by every library: the canonicalpkg-config+ meson build pattern, the universal modify-a-shipped-sample first-app workflow, the universal lifecycle, the cross-libraryDOCA_ERROR_*taxonomy, and the program-side debug order. This skill is the primitives layer the programming-guide patterns rest on.doca-debug/SKILL.md— the cross-cutting debug ladder (install / version / build / link / runtime / program / driver) and the verbosity-escalation surface. DOCA Log is the foundationdoca-debugbuilds its runtime-debug story on; this skill is where the two-tier log model and the universal lifecycle errors first surface, anddoca-debugcross-links here for both.doca-structured-tools-contract/SKILL.md— the bundle's structured-tools precedence rule (detect / prefer / fall back / report). The Command appendix in the tasks companion honors this contract.doca-hardware-safety/SKILL.md— the cross-cutting hardware-safety meta-policy this skill's## Safety policyoverlays.Per-library skills (
doca-flow,doca-rdma,doca-eth,doca-comch,doca-dma,doca-rmax,doca-sha,doca-aes-gcm,doca-erasure-coding,doca-compress,doca-dpa,doca-gpunetio,doca-pcc,doca-sta,doca-telemetry,doca-urom,doca-verbs,doca-argp,doca-devemu,doca-dpdk-bridge, …) — every per-library skill cross-links back to this skill for the foundation primitives. Loading this skill alongside any of them is the recommended default.
Files
- ATTRIBUTION.mdAdded by AutoGineer891 B
- BENCHMARK.md10.0 KiB
- CAPABILITIES.md42.3 KiB
- LICENSELicence file added by AutoGineer11.2 KiB
- SKILL.md14.7 KiB
- SKILLCARD.yaml2.7 KiB
- TASKS.md35.1 KiB
- evals/evals.json2.8 KiB
- skill-card.md4.4 KiB
- skill.oms.sig5.1 KiB
CAPABILITIES.md
DOCA Common capabilities, subsystems, version overlay, errors, observability, safety
Where to start: This file is the substance of the doca-common
foundation. Five subsystems live here as their own H2 anchors —
## log, ## buf, ## ctx, ## dev, ## progress engine — each
corresponds to a public-header family under
$(pkg-config --variable=includedir doca-common) and to a verb-side
workflow in TASKS.md. The opening ## Capabilities and modes is the routing layer that names which subsystem owns which
class of question; the closing ## Version compatibility,
## Error taxonomy, ## Observability, and ## Safety policy are
the cross-subsystem overlays.
Read this file when the loader sent you here from
SKILL.md. For step-by-step workflows that use these
capabilities (configure / build / modify / run / test / debug / use /
log) see TASKS.md. For where the underlying public
documentation and installed package paths live, defer to
doca-public-knowledge-map/SKILL.md —
do not duplicate URLs or install paths in this file.
Pattern overview
Every doca-common question this skill teaches resolves into one of SIX patterns. The patterns are CLASSES — they apply across every DOCA app and every higher-level library, not just the worked example shown.
| Common pattern | Class shape | Where the substance lives |
|---|---|---|
| 1. Establish the universal foundation | Before opening any per-library context, walk doca_devinfo_create_list → doca_dev_open → doca_pe_create → per-library doca_*_create → doca_pe_connect_ctx → doca_ctx_start → driving doca_pe_progress | ## dev, ## ctx, ## progress engine + TASKS.md ## configure |
| 2. Gate on device capability before quoting any feature | Run doca_*_cap_* against the active doca_devinfo BEFORE assuming a feature is available; the runtime cap-query is the authority, the docs are the promise | ## dev cap-query rule + TASKS.md ## use |
| 3. Wire zero-copy buffers across libraries | doca_mmap registers user memory with one or more doca_devs; doca_buf_inventory carves the registered range into doca_buf handles that flow across DOCA libraries (eth → dma → rdma → …) on the same memory | ## buf + TASKS.md ## configure, TASKS.md ## use |
| 4. Drive the progress engine on every loop iteration | doca_pe_progress is the universal task-completion drain. Submitting tasks without driving the PE is the canonical "my program does nothing" failure mode for every DOCA Core context | ## progress engine + TASKS.md ## run |
| 5. Get the two-tier log model right | SDK tier controls DOCA library internals (--sdk-log-level / doca_log_level_set_global_sdk_limit()); app tier controls user emissions (app-side registry). Independent setters, independent defaults; confusing them is the number-one first-app debug failure | ## log + TASKS.md ## log |
6. Diagnose a DOCA_ERROR_* from any Common call | Map family (BAD_STATE / INVALID_VALUE / NOT_SUPPORTED / NOT_PERMITTED / NO_MEMORY / DRIVER) to layer (lifecycle / configuration / capability / permission / resource / driver) | ## Error taxonomy + TASKS.md ## debug |
Two cross-cutting rules that apply to every pattern above:
Discover the version-installed surface, do not assume. Every pattern above gates on
pkg-config --modversion doca-commonand on the runtime cap-query against the activedoca_devinfo. Quoting a Common API symbol or a device capability without checking is the most common hallucination failure mode at the foundation layer.Lifecycle is universal across libraries.
cfg-create → cfg-set-* → init → start → use → stop → destroyis the same shape for every DOCA Core context regardless of which library it belongs to. Skipping a stage or calling an operation outside its allowed window returnsDOCA_ERROR_BAD_STATE; the right response is to re-walk the lifecycle, not to retry.
Capabilities and modes
DOCA Common is the foundation library every other DOCA library
depends on. Per the DOCA Core Programming Guide,
the Core surface ships the universal primitives every DOCA
application touches before specializing into any higher-level
library. The pkg-config module name is doca-common; it is
always present on any healthy DOCA install.
DOCA 3.5 added public capability families for buffer initialization, device-as-context conversion, device link-state query, event notification, PCIe link information, DPN PCI-address mapping, and mmap creation from a memory region. The table below names each family and points to the public header that owns the exact names and signatures; constants and prototypes are not recited here.
| Subsystem | Header family | Owning H2 in this file | Owning verb in TASKS.md |
|---|---|---|---|
Logging (two-tier SDK / app level model, source registration, DOCA_LOG_* emission, backends) | doca_log.h (under the installed infrastructure include tree) | ## log | ## log |
| Zero-copy data buffers (memory-mapping, inventory, per-buffer handles, buf pools, buf arrays) | doca_mmap.h, doca_buf.h, doca_buf_inventory.h, doca_buf_pool.h, doca_buf_array.h | ## buf | ## configure, ## use |
| Buffer initialization | doca_buf.h | ## buf | ## configure, ## use |
Context lifecycle (the universal cfg-create → start → use → stop → destroy shape every doca_*_create returns) | doca_ctx.h | ## ctx | ## configure, ## run |
| Device-as-context conversion | doca_dev.h | ## dev | ## configure |
| Device discovery (devinfo enumeration, opening, representor discovery, capability queries) | doca_dev.h | ## dev | ## configure, ## use |
| Device link-state query | doca_dev.h | ## dev | ## use |
| Event notification | doca_dev.h | ## dev | ## run |
| PCIe link information | doca_dev.h | ## dev | ## configure |
| DPN PCI-address mapping | doca_dpn.h | ## dev | ## configure |
| mmap creation from a memory region | doca_mmap.h | ## buf | ## configure |
| Progress engine (universal task-completion drain) | doca_pe.h | ## progress engine | ## run |
Adjacent Common surfaces (sync events, graphs, clocks, UAR / umem, buf arrays, mmap advise) are mentioned where they touch one of the primary subsystems. The agent's rule: when the user's question lands on one of those adjacent surfaces, route to the header on the user's install and to the public DOCA Core Programming Guide for the per-surface detail rather than reciting it here.
log
DOCA Log is DOCA's standardized logging primitive. Every DOCA library (and every shipped DOCA sample and reference application) emits its own log lines through DOCA Log, so log output from a DOCA app interoperates with DOCA's centralized level controls and downstream consumers such as the DOCA Telemetry Service.
The two-tier log-level model — the single most load-bearing rule. DOCA Log carries two independent verbosity tiers, each with its own setter and its own default. The agent MUST walk this table BEFORE writing any code:
| Tier | What it controls | How to set at runtime | Typical default | Symptom when confused |
|---|---|---|---|---|
| SDK log level | Verbosity of DOCA library internals — log lines emitted from inside the DOCA libraries themselves as they call into hardware, manage state, validate inputs, … | --sdk-log-level <N> CLI flag on any DOCA sample / reference app (numeric: 10=DISABLE, 20=CRITICAL, 30=ERROR, 40=WARNING, 50=INFO, 60=DEBUG, 70=TRACE); programmatic SDK setter doca_log_level_set_global_sdk_limit() | WARNING | User sets --sdk-log-level 60 (DEBUG) to see their own DEBUG lines and is flooded with internal DOCA spam instead, or "my own DEBUG lines do not appear" despite the flag |
| App log level | Verbosity of user code — log lines the user emits via DOCA_LOG_* macros from their own source files | App-side global lower-limit setter (doca_log_level_set_global_lower_limit); per-source via doca_logger_set_level once the source ID is in hand | INFO at steady state (per release; quote the observed default). A first diagnostic run may explicitly override it to DEBUG, then restore INFO. | User sets app level to INFO, then wonders why their DOCA_LOG_DBG-shaped lines never print; or user expects --sdk-log-level to reach their own lines and it does not |
The agent's diagnostic rule: when the user reports "my log levels do nothing", the FIRST hypothesis is tier confusion (setting one tier when they meant the other) — NOT a DOCA Log bug, NOT a hardware bug, NOT a sample issue. Walk the table above before any code-side investigation.
The objects DOCA Log exposes. The public surface is small and stable. The agent must not invent additional objects; the load-bearing call shapes are the rows below.
| Object | What it is | Lifecycle call | Used by |
|---|---|---|---|
| Log source | Per-source identity (typically one per .c file or one per component) under which DOCA_LOG_* lines are emitted | doca_log_register_source(<name>, &source_id) — called once at component init time, BEFORE any DOCA_LOG_* from that source. Mirrored by doca_log_unregister_source at teardown | The user's app, once per logical source |
DOCA_LOG_* macros | User-facing emission macros — INFO, DEBUG, ERR (ERROR), CRIT (CRITICAL), WARN (WARNING) — each takes a source ID + a printf-style format and varargs | n/a (compile-time macro expansion) | The user's app, every emission |
doca_log_level_* functions | Runtime-adjustment surface for the app-tier level (global lower / upper limit, per-source level) | n/a (call any time after the source is registered) | The user's app, on a level-change event (signal, RPC, config reload) |
| Backends / sinks | Pluggable output destinations — doca_log_backend_create_standard (the default stderr sink) plus _with_file, _with_fd, _with_buf, _with_syslog, each with an _sdk variant for the SDK tier | Created at app init time before the first DOCA_LOG_* emission; each backend has its own per-tier upper / lower level setter | The user's app, on log routing setup |
Custom-sink writes inherit the sink's own permission envelope.
When the user installs a custom backend (file, fd, buf, syslog)
instead of relying on the default stderr, the writes happen under
that sink's own permission rules — file permissions on the target
path, fd permissions inherited from the caller, syslog ACLs on the
destination. The DOCA Log API itself adds no permission elevation;
the user must ensure the process has whatever rights the sink needs.
A sink whose creation succeeds but whose writes fail is the worst
kind of "my log lines disappear" symptom — see
## Safety policy.
Path-selection — DOCA Log vs language-native logging. DOCA Log
is not the only logging framework available; the agent must walk
this rule before recommending DOCA Log setup. In a DOCA-app context
(any codebase that calls doca_*), DOCA Log is the right primitive
because its output interoperates with --sdk-log-level and with the
downstream consumers such as the DOCA Telemetry Service. In a
non-DOCA codebase with no DOCA-side context, language-native logging
(printf, fprintf(stderr, …), syslog, spdlog, Python
logging, Rust tracing, …) is fine. The anti-pattern alert:
silently swapping a sample's DOCA_LOG_* calls for printf for
simplicity is a wrong answer — it severs interop with
--sdk-log-level and the downstream consumers, and makes the
modified sample look unlike every other DOCA artifact on the host.
For the verb-side workflow (configure / build / modify / run / test /
debug a DOCA Log integration), see TASKS.md ## log.
buf
DOCA's zero-copy data plane rests on three objects layered together:
| Object | What it is | Lifecycle call |
|---|---|---|
doca_mmap | A user-space memory range registered with one or more doca_devs for device-side access. Holds memory permissions and exports for cross-process / cross-device sharing | doca_mmap_create → doca_mmap_set_memrange (or _set_dmabuf_memrange) → doca_mmap_add_dev (one or more devices) → doca_mmap_set_permissions → doca_mmap_start → use → doca_mmap_stop → doca_mmap_destroy; or doca_mmap_create_from_mr for an existing memory region |
doca_buf_inventory | A pool of doca_buf handles over one or more started doca_mmap ranges. Hands out doca_buf handles via doca_buf_inventory_buf_get_by_args | doca_buf_inventory_create → doca_buf_inventory_start → use → doca_buf_inventory_stop → doca_buf_inventory_destroy |
doca_buf | A per-operation handle into a registered memory range. Carries head pointer, length, refcount, chain-list linkage. The unit that flows between DOCA libraries on the same memory | Allocated by the inventory; reference-counted via doca_buf_inc_refcount / doca_buf_dec_refcount; direct initialization via doca_buf_get_struct_size + doca_buf_init |
DOCA 3.5 adds direct buffer initialization: doca_buf_get_struct_size returns the size to allocate for a struct doca_buf, and doca_buf_init initializes that memory over a head pointer and size. It also adds doca_mmap_create_from_mr to create a doca_mmap from an existing memory region (remote_addr, length, rkey, access_flags) on a device. Developers must use these constructors instead of assuming struct layout or manual initialization; see the public header for exact signatures.
The doca_buf_pool surface (allocate-by-pool variant) and the
doca_buf_array surface (DPA / GPU-targetable buffer arrays) are
adjacent flavors of the same model. The buf-chain primitives
(doca_buf_chain_list, doca_buf_get_next_in_list,
doca_buf_unchain_list) let the user assemble scatter-gather lists
without copying.
The same buf flows between libraries. A doca_buf allocated by
inventory A can be referenced by doca_dma on the source side and
doca_rdma on the destination side — both contexts see the same
underlying registered memory through the same handle. That is the
load-bearing property zero-copy buys: a single doca_mmap registers
once, the inventory carves it into N doca_bufs, and each doca_buf
crosses library boundaries without a second registration or a
copy.
Permissions and exports. doca_mmap_set_permissions gates
PCI_READ vs PCI_READ_WRITE vs LOCAL_READ_WRITE; the matching
cap-query family (e.g. doca_mmap_cap_is_export_pci_supported) tells
the agent whether the device supports the export class the user
wants. Exports flow through doca_mmap_export_pci / _export_rdma,
and the importing side uses doca_mmap_create_from_export to rebuild
the handle.
Lifecycle order is load-bearing. Destroying an mmap while a
buf from its inventory is still in flight returns
DOCA_ERROR_BAD_STATE; destroying a doca_dev while an mmap is
still registered on it returns the same. The teardown order is the
canonical dependency order: drain outstanding tasks → stop contexts
→ destroy library contexts → stop and destroy inventories → stop and
destroy mmaps → destroy progress engines → close devices → destroy
devinfo lists. See TASKS.md ## use for the worked
buffer-lifecycle walk.
For the verb-side workflow (configuring buffers, modifying a sample's buffer wiring), see TASKS.md ## configure and TASKS.md ## use.
ctx
doca_ctx is the universal context handle every per-library
doca_*_create returns. A doca_flow_port, a doca_rdma, a
doca_eth_txq, a doca_dma, a doca_comch_server — every one
carries an underlying doca_ctx that the user manipulates through
the universal lifecycle calls.
The lifecycle every DOCA Core context follows:
Create. Library-specific
doca_<library>_create(...)returns a handle from whichdoca_<library>_as_ctx()(where exposed) or the library's own ctx accessor surfaces the underlyingdoca_ctx *. Some libraries expose thedoca_ctx *directly; the shape is the same. For adoca_dev, use the DOCA 3.5 device-to-context conversion functiondoca_dev_as_ctx(dev)to obtain the underlyingdoca_ctx *; do not cast or assume adoca_devis adoca_ctx. See the public header for the exact signature.Configure. Library-specific
*_set_*setters apply BEFOREdoca_ctx_start. Once started, most setters returnDOCA_ERROR_BAD_STATE.Connect to a progress engine.
doca_pe_connect_ctx(pe, ctx)registers the context with a PE so its task completions surface throughdoca_pe_progress. Skipping this step is the canonical "tasks submit but nothing completes" failure mode (see## progress engine).Start.
doca_ctx_start(ctx)transitions to RUNNING. The library-specific use calls (doca_<library>_task_*_submit, …) only make sense in the RUNNING state.Use. Submit tasks, drain completions through the PE.
Stop.
doca_ctx_stop(ctx)transitions toward IDLE. Outstanding tasks must be flushed first viadoca_ctx_flush_tasksor by draining the PE untildoca_ctx_get_num_inflight_tasksreads 0.Destroy. The library-specific
doca_<library>_destroy(...)releases the context. Destroying before stop returnsDOCA_ERROR_BAD_STATE.
State-change callbacks. doca_ctx_set_state_changed_cb lets the
user observe lifecycle transitions; doca_ctx_get_state queries the
current state synchronously. Both are advisory — the lifecycle order
is the contract.
User data. doca_ctx_set_user_data / _get_user_data attaches an
opaque cookie to the context so completion callbacks can find their
owning state without a global map.
Datapath placement. doca_ctx_set_datapath_on_gpu and
_set_datapath_on_dpa are experimental setters that move a context's
datapath to a GPU or DPA target instead of the host CPU. The cap
side (doca_ctx_cap_get_num_completion_vectors,
doca_ctx_set_completion_vector) lets the user pick a completion
vector for multi-queue workloads.
For the verb-side walk of the lifecycle, see TASKS.md ## configure and TASKS.md ## run.
dev
doca_dev is the device handle every per-library context
consumes. Discovery is two-step: enumerate available devices
through doca_devinfo_create_list, then open the one the user wants
with doca_dev_open.
The discovery model:
| Object | What it is | Lifecycle call |
|---|---|---|
doca_devinfo | A read-only descriptor for a candidate device. Carries PCIe address, IB device name, interface name, IPv4 / IPv6 / MAC address, LID, and the matching cap-query family | doca_devinfo_create_list(&devinfos, &num) → iterate → doca_devinfo_destroy_list(devinfos) |
doca_dev | An opened device handle. The unit per-library contexts consume | doca_dev_open(devinfo, &dev) → use → doca_dev_close(dev) |
doca_devinfo_rep | A read-only descriptor for a representor — a host-side view of a virtual function or sub-function exposed by an embedded function (typically the DPU's eswitch) | doca_devinfo_rep_create_list(dev, filter, &reps, &num) → iterate → doca_devinfo_rep_destroy_list(reps) |
doca_dev_rep | An opened representor handle | doca_dev_rep_open(rep_info, &rep) → use → doca_dev_rep_close(rep) |
Capability discovery — the runtime-authority rule. The
doca_devinfo carries a family of capability queries — both the
generic ones (doca_devinfo_cap_is_hotplug_manager_supported,
doca_devinfo_cap_is_accelerate_resource_reclaim_supported,
doca_devinfo_cap_is_notification_moderation_supported, …) and the
library-specific ones every higher-level skill cross-links to here
(doca_flow_cap_*, doca_rdma_cap_*, doca_eth_cap_*,
doca_dma_cap_*, …). The agent's rule: **the cap-query against the
active doca_devinfo is the runtime authority for what the device
firmware + DOCA version actually supports.** The public docs are the promise; the cap-query is the reality. Quoting a feature without running the cap-query is the most common foundation-layer hallucination.
Representors are how the host sees DPU-side functions. On a
BlueField host with the DPU in switch mode, the host program opens
the host-side PF (doca_dev_open(devinfo)) and then enumerates
representors of the DPU-side VFs / SFs through
doca_devinfo_rep_create_list. The representor handle is what the
host program passes to doca_flow actions, doca_eth queues, etc.,
when steering traffic to a specific DPU-side function. The
representor-side capability queries
(doca_devinfo_rep_cap_is_filter_*_supported,
doca_devinfo_rep_get_is_uplink_representor) tell the agent what kind
of representor it is and what filters can apply.
Device-class properties. doca_devinfo_get_pci_addr_str,
_get_ibdev_name, _get_iface_name, _get_mac_addr, _get_ipv4_addr,
_get_ipv6_addr, _get_lid, _get_active_rate (experimental), _get_pci_func_type
(experimental) are the load-bearing identifiers when the user is
disambiguating among multiple devices on the host. The agent should
quote these from the user's running doca_devinfo_create_list,
never from memory.
Link up/down events (DOCA 3.5). A device can deliver asynchronous
link-up/link-down notifications from the DOCA_DEV_EVENT_TYPE_*
family, surfaced through doca_pe_progress; gate on
doca_devinfo_cap_is_event_notification_supported rather than
polling link state.
DOCA 3.5 adds doca_dev_get_link_state for polling the current link
state, with the DOCA_DEV_LINK_STATE_* family. Asynchronous
notifications use doca_dev_register_event_notification and
doca_dev_unregister_event_notification; supported event types are
the DOCA_DEV_EVENT_TYPE_* family, and the capability query is
doca_devinfo_cap_is_event_notification_supported. Notifications
surface through doca_pe_progress.
PCIe link properties (DOCA 3.5). doca_devinfo_pcie_link_get_num,
doca_devinfo_pcie_link_get_indices,
doca_devinfo_pcie_link_get_controller,
doca_devinfo_pcie_link_get_speed,
doca_devinfo_pcie_link_get_width,
doca_devinfo_pcie_link_is_dpu, and
doca_devinfo_pcie_link_is_socket_direct query PCIe link attributes
by pcie_index. Speed values use the DOCA_DEVINFO_PCIE_LINK_SPEED_*
family; width values use the DOCA_DEVINFO_PCIE_LINK_WIDTH_* family.
See the public header for exact names and signatures.
DPN mapping (DOCA 3.5). doca_dpn_cap_is_map_pci_addr_to_dpn_supported
checks whether a doca_devinfo supports mapping a PCI address to a
DPN ID; doca_dpn_map_pci_addr_to_dpn_id performs the mapping.
Buffer and memory-region helpers (DOCA 3.5).
doca_buf_get_struct_size and doca_buf_init initialize a
doca_buf; doca_mmap_create_from_mr creates a doca_mmap from a
memory region. doca_dev_as_ctx returns the device's
struct doca_ctx *.
DOCA 3.5 developer guidance. Developers must use the new getter
functions with the corresponding constant families
(DOCA_DEV_LINK_STATE_*, DOCA_DEV_EVENT_TYPE_*,
DOCA_DEVINFO_PCIE_LINK_SPEED_*, DOCA_DEVINFO_PCIE_LINK_WIDTH_*)
instead of hard-coded values; see the public header for exact names
and signatures.
For the verb-side device-discovery walk, see TASKS.md ## configure and TASKS.md ## use.
progress engine
doca_pe is the universal task-completion drain every DOCA Core
context relies on. Without it, tasks submitted into a context look
like they vanish — they completed at the hardware, but the
completion event has nowhere to surface. Driving the PE on every loop
iteration is the canonical run-loop shape for every DOCA library.
The PE model:
| Object | What it is | Lifecycle call |
|---|---|---|
doca_pe | A progress engine, owned by exactly one thread that calls doca_pe_progress on it. Tasks submitted into any connected doca_ctx surface their completions on the engine that owns the context | doca_pe_create(&pe) → connect contexts with doca_pe_connect_ctx(pe, ctx) → drive with doca_pe_progress(pe) in the run loop → doca_pe_destroy(pe) |
| Per-context connection | doca_pe_connect_ctx registers a doca_ctx with a PE so its task callbacks fire on doca_pe_progress | Called BEFORE doca_ctx_start; reversed by destroying the context |
| Notification handle | The PE exposes an OS-level fd (doca_pe_get_notification_handle) so the run loop can epoll / select it instead of polling. doca_pe_request_notification arms the fd for the next event; doca_pe_clear_notification re-arms after handling | Used by the user's run loop on a per-iteration cadence |
The single rule. Every iteration of the user's main loop calls
doca_pe_progress(pe). The function returns the number of completions
serviced this iteration; a return of zero is fine and just means
nothing was ready. Skipping the PE drive is the universal "my
program does nothing" symptom. It applies regardless of which
library the user's primary work is in (Flow / RDMA / Eth / DMA /
Comch / …).
One PE per thread is the default shape. Sharing a PE across threads requires the user's own synchronization; the simpler shape is one PE per worker thread, with all contexts that need to complete on that worker connected to that worker's PE. Multi-PE designs are valid (e.g., one PE per CPU core in a many-core data plane) but the user picks the shape; the agent does not invent multi-PE topologies.
Inflight bookkeeping. doca_pe_get_num_inflight_tasks(pe) and
the per-ctx doca_ctx_get_num_inflight_tasks(ctx) are the way to
drain on shutdown — call doca_ctx_flush_tasks (or stop the ctx)
and then loop doca_pe_progress(pe) until the count is zero before
destroying.
Notification mode. doca_pe_set_event_mode (experimental) +
doca_pe_get_notification_handle + doca_pe_request_notification
let the run loop sleep on an fd instead of busy-polling. The classic
poll loop is while (running) doca_pe_progress(pe); — fine for a
data-plane thread, wasteful for a control-plane thread, which should
prefer the notification handle.
For the verb-side walk (configuring the PE, running the drive loop, debugging missing completions), see TASKS.md ## run and TASKS.md ## debug.
Version compatibility
For the canonical DOCA version-detection chain, the four-way match
rule, NGC container semantics, and the headers-win-over-docs rule,
see doca-version/SKILL.md. The body lives
there; this skill does not duplicate it.
The doca-common-specific overlay is:
pkg-config --modversion doca-commonis the universal DOCA install anchor. It is published by every healthy DOCA install regardless of which higher-level libraries are also installed. Perdoca-version CAPABILITIES.md ## Version compatibility(doca-version/CAPABILITIES.md#version-compatibility), it joins the four-way match againstdoca_caps --version,cat /opt/mellanox/doca/applications/VERSION, and the BFB anchor (where applicable). When thepkg-configquery for doca-common fails, the install is broken — that is adoca-setup/SKILL.mdconcern, not a Common concern.The set of
doca_*symbols available is observable from the Common header set. Per the headers-win-over-docs rule indoca-version/SKILL.md, the headers under the include directory reported bypkg-config --variable=includedir doca-common(doca_buf.h,doca_ctx.h,doca_dev.h,doca_pe.h,doca_log.h,doca_mmap.h, …) are the authoritative truth for what the built library exposes. When the user reports anundefined referencefor a Common symbol, the first hypothesis is wrong-version documentation — confirm the installed version, then verify the symbol exists in the installed headers, then read the matching release notes.Common-side experimental markers. The Common ABI splits into a stable set (symbols exported under the
DOCA_2version node, seereadelf -V—doca_buf_*,doca_ctx_*,doca_dev_*,doca_pe_*,doca_mmap_*,doca_devinfo_*) and an experimental set (doca_log_*,doca_graph_*,doca_sync_event_*,doca_clock_*,doca_uar_*,doca_umem_*,doca_buf_arr_*,doca_mmap_advise_*, several newerdoca_ctx_*anddoca_devinfo_*extensions). The experimental markers are release-specific; the agent must read the installeddoca_common.hfamily on the user's install before claiming experimental-tier surface is available.No standalone
doca-log.pcin this contract. On this DOCA version the log subsystem is exposed through thedoca-commonpkg-configmodule (its public headers live under the same include root as the rest of the Common surface, resolved viapkg-config --variable=includedir doca-common). The agent's probe rule is topkg-config --exists doca-commonfirst; if a release exposes a standalonedoca-log.pc, probe that too and report which is present. The build line is whichever the probe found.DOCA 3.5 public API additions. DOCA 3.5 added the following Common functions and constants. On a DOCA 3.5 install these are part of the public surface; on older installs they are absent, so an
undefined referenceto one of them is expected unless the installed version is 3.5 or newer. Functions:doca_buf_get_struct_size,doca_buf_init,doca_dev_as_ctx,doca_dev_get_link_state,doca_dev_register_event_notification,doca_dev_unregister_event_notification,doca_devinfo_cap_is_event_notification_supported,doca_devinfo_pcie_link_get_controller,doca_devinfo_pcie_link_get_indices,doca_devinfo_pcie_link_get_num,doca_devinfo_pcie_link_get_speed,doca_devinfo_pcie_link_get_width,doca_devinfo_pcie_link_is_dpu,doca_devinfo_pcie_link_is_socket_direct,doca_dpn_cap_is_map_pci_addr_to_dpn_supported,doca_dpn_map_pci_addr_to_dpn_id,doca_mmap_create_from_mr. Constants:DOCA_DEVINFO_PCIE_LINK_SPEED_16_GT,DOCA_DEVINFO_PCIE_LINK_SPEED_2_5_GT,DOCA_DEVINFO_PCIE_LINK_SPEED_32_GT,DOCA_DEVINFO_PCIE_LINK_SPEED_5_GT,DOCA_DEVINFO_PCIE_LINK_SPEED_64_GT,DOCA_DEVINFO_PCIE_LINK_SPEED_8_GT,DOCA_DEVINFO_PCIE_LINK_SPEED_UNKNOWN,DOCA_DEVINFO_PCIE_LINK_WIDTH_UNKNOWN,DOCA_DEVINFO_PCIE_LINK_WIDTH_X1,DOCA_DEVINFO_PCIE_LINK_WIDTH_X16,DOCA_DEVINFO_PCIE_LINK_WIDTH_X2,DOCA_DEVINFO_PCIE_LINK_WIDTH_X4,DOCA_DEVINFO_PCIE_LINK_WIDTH_X8,DOCA_DEV_EVENT_TYPE_LINK_DOWN,DOCA_DEV_EVENT_TYPE_LINK_UP,DOCA_DEV_LINK_STATE_DOWN,DOCA_DEV_LINK_STATE_UP.
Version-specific tables of symbol availability are deliberately not maintained in this file except for the DOCA 3.5 additions recorded above — they would drift out of date silently. The discipline is "read the headers and the matching release notes", not "trust this file's table".
Error taxonomy
The cross-library DOCA_ERROR_* taxonomy (what each family means
and which debug layer it routes to) lives in
doca-programming-guide CAPABILITIES.md ## Error taxonomy (doca-programming-guide/CAPABILITIES.md#error-taxonomy).
The Common-specific overlay names the families the agent will see
most often from doca_buf_* / doca_ctx_* / doca_dev_* /
doca_pe_* / doca_mmap_* / doca_log_* calls and what they
specifically indicate at the foundation layer:
| Error | Common subsystem where it shows up | Common-specific cause | First action |
|---|---|---|---|
DOCA_ERROR_BAD_STATE | Any of doca_ctx_*, doca_mmap_*, doca_buf_inventory_*, doca_pe_* | Lifecycle violation. The object was operated on outside its allowed window: ctx_start before connect_ctx; mmap_add_dev after mmap_start; buf_inventory_buf_get_by_args before buf_inventory_start; pe_progress after pe_destroy. | Walk the lifecycle in ## ctx / ## buf / ## progress engine; confirm each call's preconditions BEFORE retrying. |
DOCA_ERROR_INVALID_VALUE | doca_dev_open (invalid devinfo), doca_mmap_set_memrange (bad range), doca_buf_* (out-of-range handle), doca_log_* (level enum / unregistered source) | The call's arguments did not pass validation. For doca_log, the most common cause is an unregistered source ID passed to a DOCA_LOG_* macro; for doca_mmap, a memrange that overlaps an existing range; for doca_dev_open, a devinfo that was destroyed (the destroy_list call invalidates every devinfo pointer it owned). | Re-check the call's arguments against the headers. The cap-query family is also INVALID_VALUE-prone when the devinfo passed in was destroyed — re-fetch from a live doca_devinfo_create_list. |
DOCA_ERROR_NOT_SUPPORTED | Any doca_*_cap_* query that returns false at runtime, then the actual call that depends on it. Common examples: doca_mmap_cap_is_export_pci_supported returning false followed by doca_mmap_export_pci; a doca_devinfo that does not advertise hotplug-manager support followed by the corresponding doca_dev_* call; an experimental log level (TRACE) on a release that does not expose it | The device, firmware, or DOCA version does not support what the user requested. Climb back up: drop the optional capability, choose a different device, or upgrade the install. | Re-run the cap-query against the active doca_devinfo; if false, that is the answer. Do not retry the same call on the same device. |
DOCA_ERROR_NOT_PERMITTED | doca_dev_open (insufficient permissions to open the device), doca_mmap_* (insufficient permissions on the registered memory or the device-side mapping) | Host-side env issue. Common causes: RDMA stack module loads, user not in the right group, ulimits, IOMMU mode mismatch, missing capabilities (CAP_SYS_RAWIO / CAP_NET_ADMIN depending on the device class). | Route to doca-setup TASKS.md ## debug (doca-setup/TASKS.md#debug) — the layer below the Common API is the suspect. This is not a Common-spec error. |
DOCA_ERROR_NO_MEMORY | doca_buf_inventory_buf_get_by_args (inventory pool exhausted), doca_mmap_create / _add_dev (cannot register memory), custom log sink with backpressure | Resource exhaustion. The buffer pool is sized for a maximum number of in-flight handles; exhausting it is normal back-pressure and the right response is doca_buf_dec_refcount on completed work before requesting new buffers. | Re-read ## buf for the inventory sizing rule; do not retry blindly. For the log subsystem this is rare on the default stderr sink (which does not queue) and only fires with a custom queueing backend. |
DOCA_ERROR_DRIVER | Any doca_dev_*, doca_mmap_*, or doca_ctx_* call that returns a kernel-driver-level failure | The kernel driver, firmware, or PCIe path is in a state the Common library cannot recover from. Stop. This is not a Common-spec problem. | Capture device state via the platform's diagnostic CLIs (lspci, dmesg, ibv_devinfo, mlxconfig -d <pcie> q) and escalate per doca-setup TASKS.md ## debug (doca-setup/TASKS.md#debug) driver layer. |
The agent's rule: never recommend a retry loop on DOCA_ERROR_*
from a Common call without first identifying which row above is the
cause. Retrying masks the bug; lifecycle and capability errors do
not become success on retry.
Quote doca_error_get_descr() verbatim — do not paraphrase. The
cross-cutting debug ladder
(doca-debug ## debug (doca-debug/TASKS.md#debug)) is the
canonical layered diagnosis path that the agent escalates to once
the Common-specific cause has been narrowed.
Observability
DOCA Common is the observability foundation every higher-level library builds on. The agent's job in any DOCA session is to know which observable surfaces Common exposes and which downstream consumers can read them.
| Surface | What it shows | Owning subsystem |
|---|---|---|
DOCA Log lines (default stderr sink; per-line timestamp / level / source / message) | Every DOCA library's own log lines plus the user's app's emissions. The single most reached-for observable | ## log |
| Two-tier log levels | --sdk-log-level reaches DOCA library internals; the app-side global / per-source setter reaches the user's code. Change ONE tier at a time | ## log |
| PE notification handle | doca_pe_get_notification_handle exposes an fd the run loop can epoll to know when completions are ready | ## progress engine |
| Inflight-task counts | doca_pe_get_num_inflight_tasks and doca_ctx_get_num_inflight_tasks make the drain state explicit on shutdown | ## ctx, ## progress engine |
| Capability snapshot | The output of every doca_*_cap_* query at configure time is the baseline the agent compares against when a later call returns DOCA_ERROR_NOT_SUPPORTED | ## dev |
| Context state | doca_ctx_get_state (and the _set_state_changed_cb callback) tells the user where in the lifecycle the context currently is — the load-bearing input when a call returns DOCA_ERROR_BAD_STATE | ## ctx |
| Device-info fields | doca_devinfo_get_pci_addr_str, _get_ibdev_name, _get_iface_name, _get_mac_addr, _get_active_rate give the operator-readable identity of every candidate device | ## dev |
Downstream consumers. DOCA Log output can be consumed downstream,
for example by the DOCA Telemetry Service (per
doca-public-knowledge-map/SKILL.md):
when the user pipes / forwards their app's stderr (or routes
through a custom backend), those services can consume the lines
without any in-app wiring. This is part of why DOCA Log is
preferable to printf in a DOCA-app context — the downstream shape
is the same as every other DOCA artifact on the host.
Cross-link to the cross-cutting debug ladder. The
verbosity-escalation surface is owned by ## log (the
two-tier model). The layered debug ladder the Common
observability surface feeds into is owned by
doca-debug CAPABILITIES.md ## Observability (doca-debug/CAPABILITIES.md#observability) —
which calls back here for the two-tier mechanics, the PE drive
loop, and the inflight-task drain on shutdown.
Safety policy
Overlay on the bundle-wide hardware-safety meta-policy. The rules below are this skill's per-artifact overlay on the cross-cutting rules in
doca-hardware-safetyCAPABILITIES.md ## Safety policy (doca-hardware-safety/CAPABILITIES.md#safety-policy) (specifically ### Per-artifact overlay pattern (doca-hardware-safety/CAPABILITIES.md#per-artifact-overlay-pattern)). When the two layers disagree, the stricter wins; when either layer says STOP, the agent stops.
DOCA Common's per-artifact safety surface is the disciplined lifecycle ordering every higher-level library inherits, plus the log-side guardrails the rest of the bundle relies on.
Lifecycle order is the contract for every context. Skipping
doca_pe_connect_ctxbeforedoca_ctx_start, destroying adoca_mmapwhile adoca_buffrom its inventory is still in flight, destroying adoca_devwhile a context is still using it, or callingdoca_ctx_destroybeforedoca_ctx_stopis the canonical "the program crashes far from the offending line" failure mode. The agent's response is always to walk the lifecycle in## ctx/## buf/## progress engine, not to retry. The ordering is a property of the library; ignoring it is a user-visible regression dressed up as a stack trace.Capability-query before action. Per
## dev, the cap-query against the activedoca_devinfois the runtime authority. Quoting a feature from documentation prose without running the cap-query is the most common foundation-layer hallucination. The cost is real: aNOT_SUPPORTEDat runtime surfaces far from the place the assumption was made and wastes debug budget.Custom-sink writes inherit the sink's own permission envelope. When the user installs a custom log backend (file / fd / buf / syslog) instead of relying on the default
stderr, the writes happen under that sink's own permission rules — file permissions on the target path, fd permissions inherited from the caller, syslog ACLs on the destination. The DOCA Log API itself adds no permission elevation; the user must ensure the process has whatever rights the sink needs. Validate the sink with a small write at registration time, before any production traffic.Do not log secrets through
DOCA_LOG_*. Format strings passed toDOCA_LOG_*macros take printf-style varargs; there is no automatic redaction. Anything the user passes becomes part of the line and may be forwarded downstream, for example to the DOCA Telemetry Service. TreatDOCA_LOG_*as a public-equivalent emission surface and apply the user's normal redaction discipline at the call site, not inside the library.One PE per thread is the default; cross-thread PE sharing requires the user's synchronization. Calling
doca_pe_progress(pe)from two threads on the same PE without synchronization produces interleaved completion delivery and occasional double-drain. The agent's default is to recommend one PE per worker thread; multi-PE topologies are valid but the user must own the synchronization model.No mixing of
doca_bufhandles across inventories of differentdoca_mmaps. Adoca_bufbelongs to exactly onedoca_buf_inventory, which in turn was created over exactly one set of starteddoca_mmapranges. Passing adoca_buffrom inventory A to a context that only knows inventory B is unsupported; the visible symptom isDOCA_ERROR_INVALID_VALUEat submit time or silent data corruption. The agent's first response to "can I share a buf across inventories?" is no — re-register the memory in the second inventory or use the cross-context buf flow described in## buf.
The agent's job is to enforce these orderings and discipline in the workflow, not just describe them. When the user says "skip the lifecycle, just call the API", the right answer is to refuse and explain the cost, not to comply.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
The author says: Requires DOCA SDK installed at /opt/mellanox/doca on Linux (Ubuntu 22.04/24.04 or RHEL/SLES) with a BlueField DPU or ConnectX NIC attached. doca-common is present on every healthy DOCA install; reads the user's local install via `pkg-config --modversion doca-common` and inspects /opt/mellanox/doca/{lib,include,samples,applications}. The validation steps require a live DOCA install.
Security
What our scanner noticed· Medium risk
- Large base64-encoded blobs
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- NVIDIA
- Publisher
- NVIDIA (Official)
- Source
- NVIDIA/skills · skills/doca-common · commit fce3cca
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE-APACHE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by NVIDIA or NVIDIA.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download doca-common.zip