type
status
date
slug
summary
tags
category
created days
new update day
icon
password
Created_time
Jan 24, 2025 03:20 AM
Last edited time
Mar 1, 2025 01:50 AM
最新有需要更新驱动架构,一开始不知道怎么编写对应的驱动接口与整体的驱动架构。于是就分析了一下 DPDK 的驱动架构。
DPDK 的驱动有3个层级,第一层为 bus ,总线层,第二层为 driver 层,第三层为 device 层设备层。
其中 bus 层里面包含了 driver 与 device 两个链表。
下面是 pci 总线的一个结构体定义。
  • dpdk-24.11.1\dpdk-stable-24.11.1\drivers\bus\pci\pci_common.c
可以使用下面这个文件中的接口,将驱动何设备注册进对应的 pci 总线上,以及对应的
  • dpdk-24.11.1\dpdk-stable-24.11.1\drivers\bus\pci\pci_common.c

具体的流程

rte_pci_scan

  1. rte_pci_scan()
    1. 扫描 sysfs path,对不同的 pcie addr 目录,使用 parse_pci_addr_format 函数进行设备 domain,bus,devid,function进行解析。
    2. 调用 pci_scan_one() 进行解析。然后填充设备列表。
      1. 分配对应得内存,填充对应的 vendor_id、device_id、等信息。
      2. 将 device 设备添加到 rte_pci_bus.device_list (经过排序的链表)
        1. 如果列表为空
          1. 直接插入
        2. 循环遍历 rte_pci_bus.device_list
          1. 使用 rte_pci_addr_cmp(&dev->addr, &dev2->addr); 判断应该插入的位置。从小到大进行排序。
          2. 如果设备已经注册了(addr一致的情况)。(加入对应的 bus 的设备列表中就代表注册过了。)
            1. 如果没有 probe 过。(driver 指针是否为空,如果为空的话就是没有 probe 过)
              1. 将对应的数据存储在
              如果设备已经插入,而且驱动已经 probe 。(这个情况会发生在 重复调用 rte_dev_probe 函数的时候,这个时候不需要做什么。除非驱动地址不一致,max_vfs 不一致,或者 dev_id 不一致。)
              如果没有 probe 过。(driver 指针是否为空,如果为空的话就是没有 probe 过)
              1. 将对应的数据存储在
              如果设备参数不一致,重新设置对应的参数
          3. 如果该设备在链表中已经存在,释放分配后的内存
        3. 将该设备添加到设备链表中。
    3. 遍历完目录后之后关闭对应的 dir

pci_probe

调用 probe ,循环遍历所有的设备,对于每个设备都调用 pci_probe_all_drivers 函数去匹配驱动。 对于每一个驱动调用 rte_pci_probe_one_driver 函数,循环使用每一个驱动匹配对应的设备。

rte_pci_probe_one_driver

先使用 rte_pci_match 函数,进行匹配,如果 vendor/device ID match 匹配,调用 probe() 驱动的 probe() 函数。
检查设备是否 probe 过。如果没有的话,获取设备的 iova_mode ,分配中断pci设备的中断实例。
引用驱动结构体。在 rte_pci_map_device 映射设备之前,配置驱动结构体,可以使用驱动标志配置配置。
如果驱动标志中 RTE_PCI_DRV_NEED_MAPPING ,则调用 rte_pci_map_device 进行 map。
调用 驱动的 probe 函数。如果已经 probed ,直接返回。如果出错,进行出错处理。设置对应设备的驱动。probe 之后,对应的 driver 不为 NULL。

.cleanup = pci_cleanup

进行分配的内存的清理。

.find_device = pci_find_device

循环遍历 bus 的 device 列表,使用 cmp 函数,进行查找。如果 cmp 函数返回 0 ,代表找到了。

.plug = pci_plug

plug 的时候,调用 pci_probe_all_drivers,

.unplug = pci_unplug

当设备 unplug 的时候,先调用 detach 函数,把设备 detach 掉。
 

.parse = pci_parse

 
DPDK 17,18,22 版本的编译方法什么是内存屏障?内存屏障的作用是什么?
Loading...
tangcuyu
tangcuyu
一只尘世中努力争渡的🐠
Latest posts
EtherCAT 主站 IgH 学习之 —— xenomai_posix 例程代码
2025-3-7
EtherCAT 主站 IgH 学习之 —— xenomai_posix 例程代码学习
2025-3-6
【转载】EtherCAT主站IgH解析(一)--主站初始化、状态机与EtherCAT报文 - 沐多 - 博客园
2025-3-6
如何在Debian 11上手动编译安装AMD XGBE 10GB网卡驱动
2025-3-4
内核源码中为什么会存在同一个函数的多重定义?什么是符号的强弱性?
2025-3-1
SET_NETDEV_DEV 宏详解
2025-3-1