【linux编程】RDMA接口函数

poll函数

函数原型:

struct ibv_context *ibv_open_device(struct ibv_device *device);

功能

  • 打开指定的 InfiniBand 设备
  • 返回设备上下文 (context),用于后续所有操作
  • 这是使用 InfiniBand 设备的第一步

参数

  • device: 要打开的设备指针(通过 ibv_get_device_list() 获得)

返回值

  • 成功:返回 struct ibv_context * 指针
  • 失败:返回 NULL

 

函数原型:

const char *ibv_get_device_name(struct ibv_device *device);

功能

  • 获取 InfiniBand 设备的名称
  • 返回设备名称字符串

参数

  • device: 设备指针

返回值

  • 设备名称字符串(如 "mlx5_0", "mlx4_0" 等)

 

struct ibv_pd *ibv_alloc_pd(struct ibv_context *context);

功能说明

  • 作用: 分配一个保护域 (Protection Domain, PD)
  • 用途: 保护域是 RDMA 资源的安全边界,用于隔离不同应用或用户的资源
  • 重要性: 几乎所有的 InfiniBand 资源(QP、MR、CQ等)都必须关联到某个 PD

参数

  • context: 设备上下文指针,通过 ibv_open_device() 获得

返回值

  • 成功:返回 struct ibv_pd * 指针
  • 失败:返回NULLl

 

例子:

#include <infiniband/verbs.h>
#include <stdio.h>

int main() {
    struct ibv_device **device_list;
    struct ibv_device *device;
    struct ibv_context *context;
    int num_devices;
    
    // 1. 获取设备列表
    device_list = ibv_get_device_list(&num_devices);
    if (!device_list) {
        printf("获取设备列表失败\n");
        return -1;
    }
    
    printf("找到 %d 个设备:\n", num_devices);
    
    // 2. 遍历设备并显示名称
    for (int i = 0; i < num_devices; i++) {
        device = device_list[i];
        const char *device_name = ibv_get_device_name(device);
        printf("设备 %d: %s\n", i, device_name);
    }
    
    // 3. 选择第一个设备并打开
    if (num_devices > 0) {
        device = device_list[0];
        context = ibv_open_device(device);
        if (!context) {
            printf("打开设备失败\n");
            ibv_free_device_list(device_list);
            return -1;
        }
        
        printf("成功打开设备: %s\n", ibv_get_device_name(device));
        
        // 4. 使用完毕后关闭设备
        ibv_close_device(context);
    }
    
    // 5. 释放设备列表
    ibv_free_device_list(device_list);
    
    return 0;
}

 

 

#include <infiniband/verbs.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    struct ibv_device **device_list;
    struct ibv_device *device;
    struct ibv_context *context;
    struct ibv_pd *pd;
    int num_devices;

    // 1. 获取设备列表
    device_list = ibv_get_device_list(&num_devices);
    if (!device_list || num_devices == 0) {
        fprintf(stderr, "没有找到 InfiniBand 设备\n");
        return -1;
    }

    // 2. 打开第一个设备
    device = device_list[0];
    context = ibv_open_device(device);
    if (!context) {
        fprintf(stderr, "无法打开设备 %s\n", 
                ibv_get_device_name(device));
        ibv_free_device_list(device_list);
        return -1;
    }

    // 3. 分配保护域
    pd = ibv_alloc_pd(context);
    if (!pd) {
        fprintf(stderr, "分配保护域失败\n");
        ibv_close_device(context);
        ibv_free_device_list(device_list);
        return -1;
    }

    printf("成功分配保护域: %p\n", pd);

    // 4. 在这里可以使用 PD 创建其他资源
    // - 内存区域 (MR): ibv_reg_mr(pd, ...)
    // - 完成队列 (CQ): ibv_create_cq(...)
    // - 队列对 (QP): ibv_create_qp(..., pd, ...)

    // 5. 清理资源
    if (ibv_dealloc_pd(pd)) {
        fprintf(stderr, "释放保护域失败\n");
    }

    ibv_close_device(context);
    ibv_free_device_list(device_list);

    return 0;
}

 

posted @ 2019-01-23 22:10  苏格拉底的落泪  阅读(537)  评论(0)    收藏  举报