DPDK 网卡设备scan及probe流程

本文详细介绍了DPDK中网卡设备的扫描和probe流程,包括BUS总线设备扫描、网卡驱动注册和网卡probe处理。通过X710网卡设备为例,阐述了PCI设备的注册、扫描以及资源映射过程,特别是UIO驱动在其中的作用。
摘要由CSDN通过智能技术生成

本文以X710网卡设备为例,介绍网卡的scan和probe流程的;通过本篇文章的介绍可以大致了解UIO驱动、PMD驱动之间的关联关系以及如何确认网卡对应的PMD驱动的。针对probe流程处理了解的比较片面,有了解比较深的同学,希望能找您学习一下。

1、BUS总线设备扫描

ret_bus_scan函数在目录dpdk/lib/librte_eal/common/eal_common_bus.c
初始化流程在EAL环境初始化调用 ret_bus_scan函数完成的。内部会调用各自类型的bus->scan接口;目的是扫描所有该类型bus下注册的设备。
下面有bus设备注册、以PCI设备的注册来详细说明注册流程。

1.1 Bus设备的注册

是由宏RTE_REGISTER_BUS,是一个构造函数,在程序main启动前完成的注册;将bus类型注册到全局结构rte_bus_list 链表上;目前有6中设备类型,本文主要关心网卡设备的。目前查询宏使用的地方如下。(对应宏所在文件:dpdk/lib/librte_eal/include/rte_bus.h)

 1/**
 2 * Helper for Bus registration.
 3 * The constructor has higher priority than PMD constructors.
 4 */
 5#define RTE_REGISTER_BUS(nm, bus) \
 6RTE_INIT_PRIO(businitfn_ ##nm, BUS) \
 7{\
 8  (bus).name = RTE_STR(nm);\
 9  rte_bus_register(&bus); \
10}
11RTE_REGISTER_BUS(FSL_DPAA_BUS_NAME, rte_dpaa_bus.bus);/*drivers/bus/dpaa/dpaa_bus.c*/
12RTE_REGISTER_BUS(FSLMC_BUS_NAME, rte_fslmc_bus.bus)/*drivers/bus/fslmc/fslmc_bus.c*/
13RTE_REGISTER_BUS(IFPGA_BUS_NAME, rte_ifpga_bus);/*drivers/bus/ifpga/ifpga_bus.c*/
14RTE_REGISTER_BUS(pci, rte_pci_bus.bus);/*drivers/bus/pci/pci_common.c*/
15RTE_REGISTER_BUS(vdev, rte_vdev_bus);/*drivers/bus/vdev/vdev.c*/
16RTE_REGISTER_BUS(vmbus, rte_vmbus_bus.bus);/*drivers/bus/vmbus/vmbus_common.c*/

网卡设备BUS的注册
我们重点学习网卡设备的注册,网卡设备bus已经注册到全局变量rte_bus_list链表上。

 1/*网卡bus的全局变量*/
 2struct rte_pci_bus rte_pci_bus = {
 3  .bus = { /*网卡的struct rte_bus设备内容*/
 4    .scan = rte_pci_scan,
 5    .probe = pci_probe,
 6    .find_device = pci_find_device,
 7    .plug = pci_plug,
 8    .unplug = pci_unplug,
 9    .parse = pci_parse,
10    .dma_map = pci_dma_map,
11    .dma_unmap = pci_dma_unmap,
12    .get_iommu_class = rte_pci_get_iommu_class,
13    .dev_iterate = rte_pci_dev_iterate,
14    .hot_unplug_handler = pci_hot_unplug_handler,
15    .sigbus_handler = pci_sigbus_handler,
16  },
17  /*实例化网卡设备后下挂到尾队列链表中*/
18  .device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
19  /*对应所有网卡的PMD驱动链表,下面重点说一下*/
20  .driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
21};
22/*网卡设备注册*/
23RTE_REGISTER_BUS(pci, rte_pci_bus.bus);

下面是通过gdb在全局bus链表上查找到pci设备全局变量注册信息。来打印看一下网卡设备注册后struct rte_bus 内容如下:

 1/*打印对应pci 内容*/
 2(gdb) p rte_bus_list.tqh_first[0].next.tqe_next[0].next.tqe_next[0].next.tqe_next[0]
 3$7 = {
 4  next = {/*双向链表情况*/
 5    tqe_next = 0x399cd40 <rte_vdev_bus>,
 6    tqe_prev = 0x399cb40 <rte_ifpga_bus>
 7  },
 8  name = 0x33f0f9f "pci", /*注册时的name*/
 9  scan = 0x485183 <rte_pci_scan>,
10  probe = 0x489590 <rte_pci_probe>,/*最新的代码是pci_probe*/
11  find_device = 0x489a35 <pci_find_device>,
12  plug = 0x489cf8 <pci_plug>,
13  unplug = 0x489d26 <pci_unplug>,
14  parse = 0x489835 <pci_parse>,
15  dma_map = 0x489d90 <pci_dma_map>,
16  dma_unmap = 0x489e76 <pci_dma_unmap>,
17  conf = {
18    scan_mode = RTE_BUS_SCAN_BLACKLIST
19  },
20  get_iommu_class = 0x489fc8 <rte_pci_get_iommu_class>,
21  dev_iterate = 0x488dc0 <rte_pci_dev_iterate>,
22  hot_unplug_handler = 0x489bd6 <pci_hot_unplug_handler>,
23  sigbus_handler = 0x489c70 <pci_sigbus_handler>
24}

网卡设备scan操作
在EAL环境初始化函数rte_eal_init()->rte_bus_scan()遍历全局变量rte_bus_list,调用对应bus回调函数scan。

 1int rte_bus_scan(void)
 2{
 3  int ret;
 4  struct rte_bus *bus = NULL;
 5  /*遍历bus链表,执行相应bus的scan函数*/
 6  TAILQ_FOREACH(bus, &rte_bus_list, next) {
 7    ret = bus->scan();
 8    if (ret)
 9      RTE_LOG(ERR, EAL, "Scan for (%s) bus failed.\n",
10        bus->name);
11  }
12  return 0;
13}

网卡设备调用rte_pci_scan(),函数的大致意思是打开并扫描目录“/sys/bus/pci/devices”下的PCI设备;一个目录名称表示一个pci设备;根据我们设置的网卡黑名单或白名单进行过滤,符合条件的设备,调用pci_scan_one实例化网卡设备rte_pci_device,并进行一些数据的填充(rte_pci_addr(网卡pci编号),struct rte_pci_id (网卡身份信息vendor_id、device_id来确定使用那个网卡驱动)max_vfs(sriov支持最大数量)、numa_node)。
pci_scan_one 函数只是实例化网卡设备并填充网卡的一些基本信息,并没有申请相应的资源,资源是由函数rte_bus_probe完成的。下面大概说一下具体操作流程。

1、打开目录并扫描目录“/sys/bus/pci/devices,”的网卡设备。

1root@domain 0000:00:07.0]# cd /sys/bus/pci/devices/
2[root@domain devices]# ls /*当前目录的pci设备编码如下*/
30000:00:00.0  0000:00:01.0  0000:00:01.1  0000:00:01.2  0000:00:01.3  0000:00:02.0  0000:00:03.0  0000:00:04.0  0000:00:05.0  0000:00:06.0  0000:00:07.0  0000:00:08.0

2、通过lspci | grep Eth ,我们可以知道哪些是Eth网卡设备

1[root@domain devices]# lspci | grep Eth /*但是只有四个数据以太网卡设备*/
200:03.0 Ethernet controlle
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值