Table of Contents
【免费下载链接】driver 本项目是CANN提供的驱动模块,实现基础驱动和资源管理及调度等功能,使能昇腾芯片。 项目地址: https://gitcode.com/cann/driver
- Table of Contents
- Introduction
- Installation
- Usage
- API Reference
- Key Structure Description
- FAQ
Introduction
Component Introduction
ibverbs_extend (hereinafter referred to as ibv_extend) component is an extension of standard RDMA verbs interfaces, specifically designed to support direct-drive RDMA communication in NDA (NPUDirect Async) scenarios.
The ibv_extend component achieves north-south decoupling through unified interfaces, as shown in the following figure:
- North-bound shields underlying network card hardware differences, providing transparent access for HCOMM and other communication transport layers.
- South-bound interfaces with 1825, Yunmai, and other network card extension drivers, enabling them to work without sensing upper-layer computing and memory resource differences.

The ibv_extend component provides the following core features:
- Dynamic loading and management of extension drivers
- Creation and destruction of extended QP/CQ/SRQ
- Support for north-south custom hardware operations through callback function mechanism
Application Scenarios
This component mainly applies to the following scenarios:
- Direct data transfer between NPU and RDMA network card.
- Bypassing Host CPU, direct-drive control plane between NPU and RDMA network card.

Installation
Method 1: Install through Source Compilation
-
Obtain source code and enter the component source directory.
Method 1: Use git clone to get source code.
git clone https://link.gitcode.com/i/1c86bd106dbfbff5a0d23147c09f9fa2.git cd driver/src/custom/nda/ibv_extend/Method 2: Web page download source code.
Browse to driver repository, click "Download zip" button to get the latest source code. After uploading to the server, execute the following command.
unzip driver-master.zip cd driver-master/src/custom/nda/ibv_extend/ -
Compilation dependencies.
For openEuler/CentOS/RHEL:
yum install gcc gcc-c++ make cmake libnl3-devel libudev-devel pkgconfig python3-develFor Ubuntu/Debian:
apt install gcc g++ make cmake libnl-3-dev libnl-route-3-dev libudev-dev pkg-config python3-dev -
Compile and install.
bash ./build.shTable 1 Compilation Parameter Description
Parameter
Long Parameter
Description
Usage Example
-t=TYPE
--type=TYPE
Compile type:
- release: Default value, automatically downloads rdma-core.
- debug: Debug type.
Compile in debug mode.
bash ./build.sh -t=debug-b=PATH
--libibverbs-build-dir=PATH
Specify pre-compiled rdma-core build directory. Mutually exclusive with -s parameter, cannot be used together.
Use pre-compiled rdma-core build library.
bash ./build.sh -b=/path/to/rdma-core/build-s=PATH
--libibverbs-source-dir=PATH
Specify rdma-core source directory. Mutually exclusive with -b parameter, cannot be used together.
Use custom rdma-core source code.
bash ./build.sh -s=/path/to/rdma-core-x=PATH
--libboundscheck-build-dir=PATH
Specify pre-compiled libboundscheck build directory. Mutually exclusive with -e parameter, cannot be used together.
Use pre-compiled libboundscheck build library.
bash ./build.sh -x=/path/to/libboundscheck-e=PATH
--libboundscheck-source-dir=PATH
Specify libboundscheck source directory. Mutually exclusive with -x parameter, cannot be used together.
Use custom libboundscheck source code.
bash ./build.sh -e=/path/to/libboundscheck-h
--help
Show help information.
View help information.
bash ./build.sh -h -
After compilation, check output files.
output/ ├── lib/ │ └── libibv_extend.so # Shared library └── include/ │ └── ibv_extend.h # Header file -
Dynamically specify environment variables at runtime.
export LD_LIBRARY_PATH=/path/to/ibv_extend/output/lib:$LD_LIBRARY_PATHNote:
- /path/to/ is a variable, replace with actual path.
- Users can also copy dynamic libraries under output/lib or header files under output/include to other custom paths or system paths for subsequent use.
-
Compile security function library.
Go to libboundscheck release page to get the latest source code package, for example download libboundscheck-v1.1.16.tar.gz.
Compile libc_sec.so dynamic library.
# Extract to current directory tar zxvf libboundscheck-v1.1.16.tar.gz # Enter current directory cd libboundscheck-v1.1.16 # Compile make -j # After successful compilation, dynamic link library will be generated in lib directory, need to rename to libc_sec.so. cp lib/libboundscheck.so lib/libc_sec.soNeed to depend on libc_sec.so dynamic library during use.
export LD_LIBRARY_PATH=/path/to/libboundscheck-v1.1.16/lib:$LD_LIBRARY_PATH
Method 2: Install through HDK Package
-
Install HDK software package supporting NDA feature.
- Obtain HDK software package supporting NDA feature.
- Refer to the corresponding hardware product NPU Driver and Firmware Installation Guide to complete HDK driver package installation.
-
After installation, check output files.
- libibv_extend.so is in /usr/local/Ascend/driver/lib64/driver/ directory.
- ibv_extend.h is in /usr/local/Ascend/driver/include/ directory.
-
Need to load environment variables at runtime.
-
If cann-toolkit and other development tool packages are already installed, execute the following command to load environment variables (the following command uses root user installation as example, please use actual CANN installation path).
source /usr/local/Ascend/cann/set_env.sh -
If cann-toolkit and other development tool packages are not installed, execute the following command to load environment variables.
export LD_LIBRARY_PATH=/usr/local/Ascend/driver/lib64/driver:/usr/local/Ascend/driver/lib64/common:$LD_LIBRARY_PATH
-
Usage
The ibv_extend component allows upper-layer communication libraries to dynamically load extension drivers through configuring environment variables or configuration files.
Before running, you can configure environment variable export IBV_EXTEND_SHOW_WARNINGS=1 to let ibv_extend component print Warning level logs to console. Warning level logs are not printed by default.
Before running, ensure that libibverbs.so and libibv_extend.so are correctly installed. For specific operations, refer to the table below.
Table 1 Pre-run Check
| System Type | Check/Install libibverbs.so | Check/Install libibv_extend.so |
|---|---|---|
| openEuler/CentOS/RHEL |
|
|
| Ubuntu/Debian |
|
Configure Environment Variables
Upper-layer applications can configure IBV_EXTEND_DRIVERS environment variable before running to let ibv_extend component find and load specified driver extension libraries (such as 1825, Yunmai, and other network card extension drivers). Multiple drivers are separated by : or ;.
Example: export IBV_EXTEND_DRIVERS="/path1/my_ext_driver1.so:/path2/my_ext_driver2.so"
Configuration File
-
Create extension driver configuration file directory.
mkdir -p /etc/libibverbs_extend.d/ -
Enter extension driver configuration file directory.
cd /etc/libibverbs_extend.d/ -
Create extension driver configuration file. Configuration file content format: driver <driver_name>.
Assume driver extension library is libmy_ext_driver.so, use the following command to generate configuration file.
echo "driver my_ext_driver" > my_ext_driver.conf
API Reference
Common Interfaces
ibv_extend_get_version
Function Prototype
const char *ibv_extend_get_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
Function
Get ibv_extend dynamic library version number.
Parameters
- major: Major version number. Output parameter. Can be null, null means not getting, interface does not allocate additional memory.
- minor: Minor version number. Output parameter. Can be null, null means not getting, interface does not allocate additional memory.
- patch: Patch version number. Output parameter. Can be null, null means not getting, interface does not allocate additional memory.
Return Value
Version string pointer (static string, no need to release).
Usage Example
// Call function to get version information
version_str = ibv_extend_get_version(&major, &minor, &patch);
// Print version information
printf("Version string: %s\n", version_str);
printf("Version number: %u.%u.%u\n", major, minor, patch);
ibv_extend_check_version
Function Prototype
int ibv_extend_check_version(uint32_t driver_major, uint32_t driver_minor, uint32_t driver_patch)
Function
Check version compatibility. This function checks at runtime whether the header file version used during driver and upper-layer application compilation is compatible with current library version. We recommend calling this function for version check during driver and upper-layer application initialization.
Compatibility rules:
- Major version number completely matches, then compatible.
- Software minor version number <= library minor version number, then compatible.
- If minor version numbers are the same, and software patch version number <= library patch version number, then compatible.
Parameters
- driver_major: Major version number, recommend passing IBV_EXTEND_VERSION_MAJOR.
- driver_minor: Minor version number, recommend passing IBV_EXTEND_VERSION_MINOR.
- driver_patch: Patch version number, recommend passing IBV_EXTEND_VERSION_PATCH.
Return Value
- 0: Compatible.
- -1: Incompatible.
Usage Example
// Call function to check version compatibility
ret = ibv_extend_check_version(IBV_EXTEND_VERSION_MAJOR, IBV_EXTEND_VERSION_MINOR, IBV_EXTEND_VERSION_PATCH);
// Check return value
if (ret == 0) {
printf("Version compatible, can use normally\n");
// Continue subsequent initialization operations
} else {
printf("Version incompatible, driver compilation version does not match current library version\n");
// Refuse to run
return -1;
}
North-bound Interfaces (Application Layer Call)
ibv_open_extend
Function Prototype
struct ibv_context_extend *ibv_open_extend(struct ibv_context *context)
Function
Call driver registered interface to create extension context. Must call ibv_open_extend to create extension context before calling other interfaces.
Parameters
context: Standard ibv context, created using ibv_open_device, non-null.
Return Value
- Extension context pointer: Extension context creation successful.
- NULL: Extension context creation failed.
Usage Example
// Get device list
int num_devices = 0;
struct ibv_device **dev_list = ibv_get_device_list(&num_devices);
if (!dev_list) {
fprintf(stderr, "Failed to get device list\n");
return -1;
}
// Check if there are available devices
if (num_devices <= 0) {
fprintf(stderr, "No device found\n");
ibv_free_device_list(dev_list);
return -1;
}
// Select first device
struct ibv_device *device = dev_list[0];
// Open device
struct ibv_context *ctx = ibv_open_device(device);
if (!ctx) {
fprintf(stderr, "Failed to open device\n");
ibv_free_device_list(dev_list);
return -1;
}
// Open extension context
struct ibv_context_extend *ext_ctx = ibv_open_extend(ctx);
if (!ext_ctx) {
fprintf(stderr, "Failed to open extend context\n");
ibv_close_device(ctx);
ibv_free_device_list(dev_list);
return -1;
}
ibv_close_extend
Function Prototype
int ibv_close_extend(struct ibv_context_extend *context)
Function
Call driver registered interface to release extension context resources. Cannot use this extension context resource after ibv_close_extend call.
Parameters
context: Extension context, must be created using ibv_open_extend, non-null.
Return Value
- 0: Success.
- EINVAL: Invalid parameter.
- ENOENT: Matching driver not found.
- Driver abnormal return value.
Usage Example
int ret = ibv_close_extend(ext_ctx);
if (ret != 0) {
fprintf(stderr, "Failed to close extend context: %d\n", ret);
}
South-bound Interfaces (Driver Call)
verbs_register_driver_extend
Function Prototype
void verbsregister_driver_extend(const struct verbs_device_extend_ops *ops) or PROVIDER_EXTEND_DRIVER(drv)
Function
Register driver to extend_driver_list linked list. Can use encapsulated PROVIDER_EXTEND_DRIVER macro.
Parameters
- ops: Device extension operation structure pointer, non-null, internally does not allocate additional address, must be global static variable.
- drv: Must be struct verbs_device_extend_ops type.
Return Value
None.
Usage Example
static const struct verbs_device_extend_ops my_driver_ops = {
.name = "my_driver", // Must be consistent with standard driver
.alloc_context = my_alloc_context,
.free_context = my_free_context,
};
PROVIDER_EXTEND_DRIVER(my_driver_ops); // Use macro for automatic registration
Key Structure Description
Enum Type Definition
queue_buf_dma_mode
During extended QP/CQ/SRQ resource creation, for these resources, driver needs to establish host address and device address mapping so that device can directly drive network card resources. Currently supports two mapping modes.
| Variable | Value | Description |
|---|---|---|
| QU_BUF_DMA_MODE_DEFAULT | 0 | PCIe mapping mode, this mode supports general hardware form, network card and NPU are both PCIe devices, usually use peerMem mode mapping. |
| QU_BUF_DMA_MODE_INDEP_UB | 1 | UB mapping mode, network card and NPU are PCIe devices, but data path uses independent UB bus addressing, usually use UbShmem mode mapping. |
doorbell_map_mode
During extended QP/CQ/SRQ resource creation, driver will allocate doorbell address, and needs to map host-side allocated doorbell address to NPU card side. Mapping logic (db_mmap) is implemented by upper layer. Upper layer needs to perform mapping based on mapping type provided by driver.
| Variable | Value | Description |
|---|---|---|
| DB_MAP_MODE_HOST_VA | 0 | Based on Host virtual address mapping, usually third-party network card resource mapping method. |
| DB_MAP_MODE_UB_RES | 1 | Use UB device resource descriptor for mapping, 1825 network card used mapping method. |
memcpy_direction
When driver uses upper-layer registered memcpy_s to copy memory, need to specify copy direction to allow driver read/write access to device memory.
| Variable | Value | Description |
|---|---|---|
| MEMCPY_DIR_HOST_TO_HOST | 0 | memcpy_s parameter, copy within Host. |
| MEMCPY_DIR_HOST_TO_DEVICE | 1 | memcpy_s parameter, memory copy from Host to Device (NPU). |
| MEMCPY_DIR_DEVICE_TO_HOST | 2 | memcpy_s parameter, memory copy from Device (NPU) to Host. |
| MEMCPY_DIR_DEVICE_TO_DEVICE | 3 | memcpy_s parameter, memory copy within Device (NPU) or between Device (NPU). |
ibv_qp_init_cap
When creating extended QP, upper-layer communication library can specify additional extension configuration, optional.
| Variable | Value | Description |
|---|---|---|
| QP_ENABLE_DIRECT_WQE | 1 | If network card supports direct_wqe capability, by configuring this field, can enable network card direct_wqe capability when calling ibv_create_qp_extend interface to create sq_info. |
ibv_extend_device_cap
Device supported extension capabilities, returned by extension query interface. Driver queries whether current device supports NDR/NDA.
| Variable | Value | Description |
|---|---|---|
| IBV_EXTEND_NDR | 1 | Device supports NDR (NPUDirect Rdma) capability. |
| IBV_EXTEND_NDA | 2 | Device supports NDA (NPUDirect Async) capability. |
Core Data Structures
doorbell_map_desc
doorbell_map descriptor is used for driver-side mapping of hardware doorbell address. After driver allocates doorbell, maps it to NPU through db_map callback passed by upper layer for NPU direct-drive.
| Variable | Type | Description |
|---|---|---|
| hva | uint64_t | doorbell virtual address on host side, PCIe network card uses, address must be valid. |
| ub_res | struct | UB mapping method uses, uses UB resource descriptor, address must be valid. See structure description below. |
| size | uint64_t | doorbell mapping length. |
| type | uint32_t | doorbell mapping type (doorbell_map_mode type). |
| resv | uint32_t | Reserved. |
struct {
uint64_t guid_l; /* GUID low 64 bits */
uint64_t guid_h; /* GUID high 64 bits */
struct {
uint64_t resource_id : 4; /* Corresponds to res_id in GUID */
uint64_t offset : 32; /* Offset within a page id of a certain GUID */
uint64_t resv : 28; /* Reserved */
} bits;
} ub_res;
ibv_extend_ops
This series of functions is used for memory allocation and mapping during QP/CQ/SRQ and other resource creation. Upper-layer application implements, for underlying driver callback use.
| Function Prototype | Function Description | Input Parameter Description | Return Value Description |
|---|---|---|---|
void *(*alloc)(size_t size) | Used by underlying driver to request memory resources, can be NPU memory resources or host memory resources. | size: Allocation length, unit bytes, greater than 0. | Allocated memory pointer, returns null on allocation failure. |
void (*free)(void *ptr) | Used by underlying driver for memory release. Memory must be address allocated by alloc callback function. | ptr: Memory pointer allocated using alloc interface. | No return value. |
void (*memset_s)(void *dst, int value, size_t count) | Used by underlying driver for memory initialization operation. Memory must be address allocated by alloc callback function. |
| No return value. |
int (*memcpy_s)(void *dst, size_t dst_max_size, void *src, size_t size, uint32_t direct) | Used by underlying driver for memory copy operation. Memory must be address allocated by alloc callback function. |
| Returns 0 on success, returns negative error code on failure. |
void *(*db_mmap)(struct doorbell_map_desc *desc) | Used for doorbell mapping logic, usually implements logic of mapping host doorbell address to NPU memory. Implementation constraint: Must support repeated mapping of same desc, that is, multiple mappings of same desc address must return same mapping address. | desc: doorbell resource mapping descriptor. | Mapped address pointer, returns null on failure. |
int (*db_unmap)(void *ptr, struct doorbell_map_desc *desc) | Used for unmapping logic. |
| Returns 0 on success, returns negative error code on failure. |
FAQ
Error when calling ibv_open_extend interface to initialize extension library
Problem Description
Upper-layer communication component calls ibv_open_extend interface returns null pointer. After configuring IBV_EXTEND_SHOW_WARNINGS environment variable, error as follows:
ibv_extend: Warning: no available ops for open extend context
Possible Cause
ibv_extend extension library cannot find corresponding network card extension driver or dlopen corresponding network card extension driver reports error.
Solution
-
Refer to Usage, let ibv_extend find corresponding network card extension driver location.
-
If using dlopen method to load libibv_extend.so, need to export symbols to global symbol table through RTLD_GLOBAL. Usage example as follows.
void *handle = dlopen("libibv_extend.so", RTLD_LAZY | RTLD_GLOBAL); if (!handle) { fprintf(stderr, "dlopen libibv_extend.so error: %s\n", dlerror()); return; } -
If still reports error, contact corresponding network card extension driver vendor to confirm whether extension driver package is correct.
【免费下载链接】driver 本项目是CANN提供的驱动模块,实现基础驱动和资源管理及调度等功能,使能昇腾芯片。 项目地址: https://gitcode.com/cann/driver
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



