使用 dpdk-pmdinfo.py 脚本获取 dpdk 程序支持的设备及其实现原理

版本信息

dpdk 版本:dpdk-22.11-rc0

方法

usertools/dpdk-pmdinfo.py -d /usr/share/misc/pci.ids ./dpdk-testpmd

输出示例:

PMD NAME: net_ixgbe
PMD PARAMETERS: fiber_sdp3_no_tx_disable=<0|1>
PMD KMOD DEPENDENCIES: * igb_uio | uio_pci_generic | vfio-pci
PMD HW SUPPORT:
 Intel Corporation (8086) : 82598 10GbE PCI-Express Ethernet Controller (10b6) (All Subdevices)
 Intel Corporation (8086) : 82598EB Gigabit BX Network Connection (1508) (All Subdevices)
 Intel Corporation (8086) : 82598EB 10-Gigabit AF Dual Port Network Connection (10c6) (All Subdevices)
 Intel Corporation (8086) : 82598EB 10-Gigabit AF Network Connection (10c7) (All Subdevices)
 Intel Corporation (8086) : 82598EB 10-Gigabit AT Network Connection (10c8) (All Subdevices)
 Intel Corporation (8086) : 82598EB 10-Gigabit AT2 Server Adapter (150b) (All Subdevices)
 Intel Corporation (8086) : 82598EB 10-Gigabit Dual Port Network Connection (10db) (All Subdevices)
 Intel Corporation (8086) : 82598EB 10-Gigabit AT CX4 Network Connection (10dd) (All Subdevices)
 Intel Corporation (8086) : 82598EB 10-Gigabit AT CX4 Network Connection (10ec) (All Subdevices)
 Intel Corporation (8086) : 82598EB 10-Gigabit AF Dual Port Network Connection (10f1) (All Subdevices)
 Intel Corporation (8086) : 82598EB 10-Gigabit AF Dual Port Network Connection (10e1) (All Subdevices)
 Intel Corporation (8086) : 82598EB 10-Gigabit AF Network Connection (10f4) (All Subdevices)
 Intel Corporation (8086) : 10 Gigabit BR KX4 Dual Port Network Connection (10f7) (All Subdevices)
 Intel Corporation (8086) : Ethernet X520 10GbE Dual Port KX4 Mezz (1514) (All Subdevices)
 Intel Corporation (8086) : 82599ES 10 Gigabit Network Connection (1517) (All Subdevices)
 Intel Corporation (8086) : 82599 10 Gigabit Dual Port Backplane Connection (10f8) (All Subdevices)
 Intel Corporation (8086) : 82599 10 Gigabit Dual Port Network Connection (10f9) (All Subdevices)
 Intel Corporation (8086) : 82599ES 10-Gigabit SFI/SFP+ Network Connection (10fb) (All Subdevices)
 Intel Corporation (8086) : 82599 10 Gigabit Dual Port Backplane Connection with FCoE (152a) (All Subdevices)
 Intel Corporation (8086) : 82599 10 Gigabit Dual Port Network Connection with FCoE (1529) (All Subdevices)
 Intel Corporation (8086) : Ethernet Express Module X520-P2 (1507) (All Subdevices)
 Intel Corporation (8086) : Ethernet 10G 2P X520 Adapter (154d) (All Subdevices)

PMD NAME 为驱动的名称,PMD PARAMETERS 为驱动支持的参数,PMD KMOD DEPENDENCIES 表示驱动依赖的 passthrough 内核驱动,PMD HW SUPPORT 为此驱动支持的设备列表。

实现原理

在 dpdk pmd 驱动中,使用驱动的名称以及支持的设备列表信息,使用宏生成一个特定前缀与后缀的字符串数组,数组中保存驱动支持的设备列表结构的名称。

i40e 中使用如下代码进行注册:

RTE_PMD_REGISTER_PCI_TABLE(net_i40e, pci_id_i40e_map);
RTE_PMD_REGISTER_KMOD_DEP(net_i40e, "* igb_uio | uio_pci_generic | vfio-pci");

如上代码经过预处理,会生成如下数组定义:

static const char __net_i40e_pci_tbl_export[] __rte_used = "pci_id_i40e_map";
static const char __net_i40e_kmod_dep_export[] __rte_used = "* igb_uio | uio_pci_generic | vfio-pci";

pci_id_i40e_map 为 i40e 支持的 pci 设备列表,其定义部分摘录如下:

static const struct rte_pci_id pci_id_i40e_map[] = {
	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_XL710) },
	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QEMU) },
	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_B) },
	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_C) },
	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_A) },
	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_B) },

drivers 目录中的 meson.build 脚本中有如下命令:

        # generate pmdinfo sources by building a temporary
        # lib and then running pmdinfogen on the contents of
        # that lib. The final lib reuses the object files and
        # adds in the new source file.
        out_filename = lib_name + '.pmd.c'
        tmp_lib = static_library('tmp_' + lib_name, sources,
                include_directories: includes,
                dependencies: static_deps,
                c_args: cflags)
        objs += tmp_lib.extract_all_objects(recursive: true)
        sources = custom_target(out_filename,
                command: [pmdinfo, tmp_lib.full_path(), '@OUTPUT@', pmdinfogen],
                output: out_filename,
                depends: [tmp_lib])

在编译生成驱动静态库之前,先编译临时的驱动静态库。然后调用自定义命令 pmdinfo 来生成 *pmd.c 文件并更新编译源码列表。pmdinfo 命令定义如下:

./buildtools/meson.build:25:pmdinfo = py3 + files('gen-pmdinfo-cfile.py') + [meson.current_build_dir()]

pmdinfo 命令调用 gen-pmdinfo-cfile.py 脚本,此脚本首先使用 ar -t 命令获取临时库中目标文件列表,然后调用 pmdinfogen.py 脚本来扫描所有的目标文件,遍历 elf 格式文件符号表匹配以 pci_tbl_export 以及 dep_export 后缀结尾的对象,根据对象的内容找到相应的表结构,然后在 drivers 编译目录中生成后缀为 .pmd.c 的源文件并更新驱动库的 sources 列表加入生成的 xxx.pmd.c 源文件。

i40e 驱动 pmd.c 源文件内容如下:

$ cat ./drivers/rte_net_i40e.pmd.c 
static __attribute__((unused)) const char *generator = "../buildtools/pmdinfogen.py";
const char net_i40e_pmd_info[] __attribute__((used)) = "PMD_INFO_STRING= {\"name\": \"net_i40e\", \"params\": \"enable_floating_veb=1floating_veb_list=<string>queue-num-per-vf=1|2|4|8|16support-multi-driver=1\", \"kmod\": \"* igb_uio | uio_pci_generic | vfio-pci\", \"pci_ids\": [[32902, 5490, 65535, 65535], [32902, 5492, 65535, 65535], [32902, 5504, 65535, 65535], [32902, 5505, 65535, 65535], [32902, 5507, 65535, 65535], [32902, 5508, 65535, 65535], [32902, 5509, 65535, 65535], [32902, 5510, 65535, 65535], [32902, 5511, 65535, 65535], [32902, 5512, 65535, 65535], [32902, 5513, 65535, 65535], [32902, 5514, 65535, 65535], [32902, 5515, 65535, 65535], [32902, 14156, 65535, 65535], [32902, 14286, 65535, 65535], [32902, 14287, 65535, 65535], [32902, 14288, 65535, 65535], [32902, 14289, 65535, 65535], [32902, 14290, 65535, 65535], [32902, 14291, 65535, 65535], [32902, 3320, 65535, 65535], [32902, 3416, 65535, 65535], [32902, 5631, 65535, 65535], [32902, 4127, 65535, 65535], [32902, 4175, 65535, 65535], [32902, 4174, 65535, 65535]]}";

可以看到它定义了一个以 pmd_info 结尾的字符变量,此变量的值为 json 格式的驱动支持列表。

此后重新编译生成的静态库中就会带有 xxx.pmd.c.o 的目标文件,i40e 驱动库中文件列表示例如下:

$ ar -t  ./drivers/librte_net_i40e.a
meson-generated_.._rte_net_i40e.pmd.c.o
......................................
net_i40e_rte_pmd_i40e.c.o
net_i40e_i40e_rxtx_vec_sse.c.o
net_i40e_i40e_rxtx_vec_avx2.c.o

可以看到 net_i40e_rte_pmd_i40e.c.o 就是其中 i40e 驱动库的 pmd.c.o 目标文件。此后链接 dpdk 驱动库生成的 dpdk 程序中将会包含 xxx_pmd_info 符号,示例如下:

$ nm ./dpdk-testpmd | grep i40e_pmd_info
00000000018abf00 R net_i40e_pmd_info

最后 dpdk-pmdinfo.py 解析 elf 文件,在 .rodata section 中查找以 PMD_INFO_STRING 开始的位置,使用 json 库解析信息,然后使用指定的 pci.ids 生成程序支持的设备信息并格式化输出就完成了所有过程。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值