RDMA--libibverbs代码分析(2)-设备发现

摘要:
要生成这个目录,我们需要加载ib_uverbs.ko。大体知道了ib_uverbs.ko的作用,我们来看一下它的具体实现。staticint__initib_uverbs_init{intret;//向系统注册字符设备之前,应首先调用该函数,向系统申请设备号ret=register_chrdev_region;……在libmlx5代码中,mlx5.c,就会调用PROVIDER_DRIVER来初始化用户态驱动。综上,我们可以总结出,libibverbs与libmlx5用户态驱动紧密配合下,发现mlx5驱动设备,而不是通过pcie,而ib_uverbs.ko,mlx5内核态驱动,是提供支持。

基于上一篇文章https://www.cnblogs.com/xingmuxin/p/11057845.html

我们现在从分析libibverbs代码,跳入到分析内核代码,代码位置在./drivers/infiniband/core/uverbs_main.c,在这里,我们主要来探究,infiniband_verbs这个文件目录的创建。要生成这个目录,我们需要加载ib_uverbs.ko。下面我们看下这个ko是如何编译的。

infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS)      :=rdma_cm.o
user_access-$(CONFIG_INFINIBAND_ADDR_TRANS)     :=rdma_ucm.o

obj-$(CONFIG_INFINIBAND) +=ib_core.o ib_cm.o iw_cm.o 
                                        $(infiniband-y)
obj-$(CONFIG_INFINIBAND_USER_MAD) +=ib_umad.o
obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o $(user_access-y)
obj-$(CONFIG_INFINIBAND_USER_ACCESS_UCM) += ib_ucm.o $(user_access-y)
……
CONFIG_INFINIBAND_USER_ACCESS这个编译选项的解释为:
Userspace InfiniBand access support. This enables the kernel side of userspace verbs and the userspace communication manager (CM). This allows userspace processes to set up connections and directly access InfiniBand hardware for fast-path operations. You will also need libibverbs, libibcm and a hardware driver library from rdma-core https://github.com/linux-rdma/rdma-core.
也就是说ib_uverbs.ko是为用户态直接访问infiniband硬件提供支持的,我们除了需要libibverbs,libibcm外,还需要硬件驱动library

大体知道了ib_uverbs.ko的作用(这里的u,我理解应该是userspace),我们来看一下它的具体实现。

static int __init ib_uverbs_init(void)
{
    intret;
    // 向系统注册字符设备之前,应首先调用该函数,向系统申请设备号
ret
=register_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_NUM_FIXED_MINOR, "infiniband_verbs"); …… ret = alloc_chrdev_region(&dynamic_uverbs_dev, 0, IB_UVERBS_NUM_DYNAMIC_MINOR, "infiniband_verbs"); ……
// 在/sys/class/目录下创建一个infiniband_verbs目录 uverbs_class
= class_create(THIS_MODULE, "infiniband_verbs"); if(IS_ERR(uverbs_class)) { ret =PTR_ERR(uverbs_class); pr_err("user_verbs: couldn't create class infiniband_verbs "); gotoout_chrdev; } uverbs_class->devnode =uverbs_devnode; ret = class_create_file(uverbs_class, &class_attr_abi_version.attr); if(ret) { pr_err("user_verbs: couldn't create abi_version attribute "); gotoout_class; } ret = ib_register_client(&uverbs_client); if(ret) { pr_err("user_verbs: couldn't register client "); gotoout_class; } return 0; …… }

以上似乎是创建udev的一些固定操作,要在/sys/class目录下创建对应的文件夹目录。

接下来,我们再回到libibverbs代码中,在find_sysfs_devs后,会遍历sysfs_dev_list,执行try_drivers,try_drivers代码如下:

static struct ibv_device *try_drivers(struct ibv_sysfs_dev *sysfs_dev)
{
    struct ibv_driver *driver;
    struct ibv_device *dev;

    for (driver = head_driver; driver; driver = driver->next) {
        dev =try_driver(driver, sysfs_dev);
        if(dev)
            returndev;
    }

    returnNULL;
}

这里关键点是head_driver在没有赋值前它是空的,我们看下哪里会给head_driver赋值,从代码看是在调用ibv_register_driver时会给head_driver赋值,这个ibv_register_driver函数在libibverbs代码中搜索不到调用处,在driver.h文件中,定义一个宏为:

#define PROVIDER_DRIVER(drv)                                                   
    static __attribute__((constructor)) void drv##__register_driver(void)  
    {                                                                      
        verbs_register_driver(&drv);                                   
    }
__attribute__((constructor))设置了优先级属性,constructor参数让系统执行main()函数之前调用函数。
搜索PROVIDER_DRIVER,发现所有rdma驱动,都是使用这个函数来初始化他们的用户态库的。我们以mlx5为例。在libmlx5代码中,mlx5.c(可以参看rdma-core/providers/mlx5.c),就会调用PROVIDER_DRIVER来初始化用户态驱动。
综上,我们可以总结出,libibverbs与libmlx5用户态驱动紧密配合下,发现mlx5驱动设备,而不是通过pcie,而ib_uverbs.ko,mlx5内核态驱动,是提供支持。那么现在的问题是,用户态驱动都是这样操作的吗,普通的设备驱动是如何进行设备发现的呢?
下一节我们来讨论这个问题。

免责声明:文章转载自《RDMA--libibverbs代码分析(2)-设备发现》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SSH整合报错:No result defined for action and result input磁盘IO读写流程图下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

怎样将shp文件的坐标点导出来?

单击以选择保存类型中的文本文件,将经度和纬度输出为txt格式。坐标系统有两个选项。第一个是数据源的坐标系。数据的数据源坐标系为UTM,投影坐标系,单位为米。第二个是我开始设置的数据帧的坐标系,即WGS84,单位为度。。。。直接将获得的点的坐标生成到文本文件中。如果它是栅格文件,则来自rastrastertopint的arctoolboxconverttool...

IDEA 运行键是灰色

版权声明:本文为博主原创文章,遵循CC4.0BY-SA版权协议。转载请附上原始来源链接和本声明。本文链接:https://blog.csdn.net/Butterfly_resting/article/details/89388149原因是我们的新项目没有选择源目录,如图所示:解决方案:IDEA提供了选择源目录的快速设置。右键单击src并选择MarkDire...

浅谈 SQL 注入(注入篇)

1、 SQL注入1.1简介什么是SQL注入?它不过滤用户可以严格控制或没有限制的参数,以便用户可以将传入的参数和SQL语句组合成SQL语句,然后将其传输到web服务器。最后,它被传输到数据库以执行添加、删除、修改和查询等操作。基于此,用户可以获取数据库数据或提高其销毁数据库数据的权限。...

es6 proxy浅析

代理用于定义用户定义的基本操作行为,如搜索、分配、枚举、函数调用等。代理接受要代理的目标对象和一些包含元操作的对象,为要代理的对象创建“屏障”,拦截所有操作,并将其重定向到用户定义的元操作对象。然而,proxy提供了一种更好的方法来实现类似的私有属性constenablePrivate==˃newProxy(target,{has:(obj,k)=˃(!pr...

Winform知识点

BringToFront()将控件移动到Z顺序的前面。...

mac下vscode插件位置

1、 位置:Mac:User/(您的用户名)/vscode/extensions II下vscode插件的存储位置。搜索步骤:以我的mac为例,打开查找器,单击远程CD,单击转到上面的文件夹,单击macintosh HD,单击用户(或用户),单击mymac,单击。vscode(.vscode是一个隐藏文件。如果默认情况下不显示,请按住ctrl+shift+....