openeuler加载dpdk驱动模块

虽然是openeuler arm架构加载dpdk网卡驱动,但是linux加载驱动模块的流程和方法是一样的,遇到的问题也是相似的,所以借这个机会把相关的内容介绍一下

确认模块名称

驱动模块开发完成后是一个ko库,拷贝到系统指定目录,然后运行命令加载模块名。有时候想知道源码编译的模块名称是什么,可以在源码的Makefile文件中查找:

#
# module name and path
#
MODULE = igb_uio
MODULE_PATH = drivers/net/igb_uio

_BUILD = $(MODULE).ko

如果使用uio,需要加载uio_pci_generic(系统默认)
如果使用vfio,需要加载vfio(系统默认)和vfio-pci(系统默认)
如果使用igb_uio,需要加载uio(系统默认)和igb_uio(编译得到)。但是新版本的dpdk不再使用igb_uio(虽然还可以打开配置进行编译),

命令介绍

操作驱动相关命令

insmod

insmod只会加载指定路径下的某个模块,不会解决依赖,比如insmod /home/dev/igb_uio.ko

modprobe

modprobe会帮忙解决依赖,也就是如果加载a模块需要b模块,那么会先加载b模块,再加载a模块,比如modprobe igb_uio
modprobe不需要指定具体路径,但是你必须要把你的模块放到系统指定目录/lib/modules/#uname -r#/,这个路径不是固定的,会根据不同的系统而不一样,uname -r就是后面的目录名称。

depmod

depmod会扫描模块,把结果写入/lib/modules/#uname -r#/modules.dep文件中,如果安装一个新模块,需要先运行depmod扫描,再运行modprobe加载,不然会报错FATAL: Module igb_uio.ko not found in directory /lib/modules/xxx

lsmod

列出系统中安装的模块,内容有三列,第一列是模块名,第二列是模块大小,第三列是模块被谁调用

Module                  Size  Used by
ib_uverbs             327680  1 rdma_ucm
ib_iser               262144  0
rdma_cm               262144  6 rpcrdma,ib_srpt,ib_srp,ib_iser,ib_isert,rdma_ucm

modinfo

查看模块的信息,可以指定具体路径,也可以不指定

$ modinfo igb_uio                
filename:       /lib/modules/4.19.90-2003.4.0.0036.oe1.aarch64/extra/dpdk/igb_uio.ko
author:         Intel Corporation
license:        GPL
description:    UIO driver for Intel IGB PCI cards
srcversion:     26C63DAE2104091D5DE47C6
depends:        uio
name:           igb_uio
vermagic:       4.19.90-2110.8.0.0119.oe1.aarch64 SMP mod_unload modversions aarch64
parm:           intr_mode:igb_uio interrupt mode (default=msix):
    msix       Use MSIX interrupt
    msi        Use MSI interrupt
    legacy     Use Legacy interrupt

 (charp)

rmmod

删除模块,如果模块不需要了,或者想替换新的模块,需要用rmmod删除,命令如下rmmod igb_uio

module_init module_exit

这两个函数注册两个接口,用作加载和卸载模块的时候调用

module_init(mymodule_init);
module_exit(mymodule_exit);

操作设备与驱动命令

绑定驱动

dpdk-devbind -b igb_uio 0000:c6:00.0

dpdk-devbind是dpdk编译安装的工具,上面就是把igb_uio驱动绑定到指定的网卡bus info中

可以查看这个脚本,实际上就是把网卡的bus总线id写入到/sys/bus/pci/drivers/igb_uio/bind文件中,如果想把哪个设备绑定到一个驱动上,就把这个设备的bus id写入到对应驱动目录/sys/bus/pci/drivers/xxx/bind中,xxx就是这个驱动的名字。这个文件只有只写的权限,所以可以用echo 0000:c6:00.0 > /sys/bus/pci/drivers/igb_uio/bind实现,也可以通过fopen以只写的方式写入

除此之外,还有一些特殊处理,比如先卸载原先驱动或者绑定的驱动本身属于dpdk等。

查看网卡状态

dpdk-devbind -s

Network devices using DPDK-compatible driver
============================================
0000:c6:00.0 'Hi1822 Family (4*25GE) 1822' drv=igb_uio unused=hinic

Network devices using kernel driver
===================================
0000:7d:00.0 'HNS GE/10GE/25GE RDMA Network Controller a222' if=enp125s0f0 drv=hns3 unused=hns_roce_hw_v2,igb_uio *Active*
0000:7d:00.1 'HNS GE/10GE/25GE Network Controller a221' if=enp125s0f1 drv=hns3 unused=hclge,igb_uio 
0000:7d:00.2 'HNS GE/10GE/25GE RDMA Network Controller a222' if=enp125s0f2 drv=hns3 unused=hns_roce_hw_v2,igb_uio 
0000:7d:00.3 'HNS GE/10GE/25GE Network Controller a221' if=enp125s0f3 drv=hns3 unused=hclge,igb_uio 
0000:c3:00.0 'Hi1822 Family (4*25GE) 1822' if=enp195s0 drv=hinic unused=igb_uio 
0000:c4:00.0 'Hi1822 Family (4*25GE) 1822' if=enp196s0 drv=hinic unused=igb_uio 
0000:c5:00.0 'Hi1822 Family (4*25GE) 1822' if=enp197s0 drv=hinic unused=igb_uio 
0000:dd:00.0 'HNS GE/10GE/25GE RDMA Network Controller a222' if=enp221s0f0 drv=hns3 unused=hns_roce_hw_v2,igb_uio

可以看到0000:c6:00.0这个网卡已经是dpdk的驱动了。

绑定dpdk驱动后,网卡会被dpdk接管,使用ifconfig就无法查看到网卡信息和名称。

同样可以查看这个脚本,实际上还是用了lspci ip等相关命令整合的信息

解绑网卡驱动

dpdk-devbind -u 0000:c6:00.0

查看脚本可以知道解绑和绑定驱动类似,把bus id写入到对应驱动的/sys/bus/pci/drivers/xxx/unbind中。

遇到问题

modprobe: ERROR: could not insert 'igb_uio': Invalid argument

当前系统的内核和编译模块内核不匹配,通过uname -rmodinfo 模块名查看系统内核与模块的vermagic值是否相同。

$ uname -r
4.19.90-2003.4.0.0036.oe1.aarch64

$ modinfo igb_uio 
filename:       /lib/modules/4.19.90-2003.4.0.0036.oe1.aarch64/extra/dpdk/igb_uio.ko
author:         Intel Corporation
license:        GPL
description:    UIO driver for Intel IGB PCI cards
srcversion:     26C63DAE2104091D5DE47C6
depends:        uio
name:           igb_uio
vermagic:       4.19.90-2110.8.0.0119.oe1.aarch64 SMP mod_unload modversions aarch64
parm:           intr_mode:igb_uio interrupt mode (default=msix):
    msix       Use MSIX interrupt
    msi        Use MSI interrupt
    legacy     Use Legacy interrupt

 (charp)
parm:           wc_activate:Activate support for write combining (WC) (default=0)
    0 - disable
    other - enable
 (int)

这时候可以查看一下自己系统上安装的kernel-devel与系统内核版本uname -r是否匹配,如果不匹配,先卸载kernel-devel,再安装指定版本yum install "kernel-devel-uname-r == $(uname -r)"

insmod: ERROR: could not insert module igb_uio.ko: Unknown symbol in module

这是因为有依赖模块,查看依赖模块名称

modinfo igb_uio.ko|grep depends
depends:        uio

安装依赖模块modprobe uio
再次安装insmod igb_uio.ko

EAL: Error - exiting with code: 1 Cause: No Ethernet ports - bye

可以通过dmesg查看出错日志,可能原因是驱动与内核版本不匹配,或者加载驱动失败。

目前遇到的问题就是dpdk的驱动没有加载,或者加载出错,反正就是dpdk驱动加载有问题,导致程序无法获得网口信息。

加载原生驱动

有时候需要还原驱动,可以在最开始调用ethtool -i 网卡名查看

如果加载了dpdk驱动,而忘记或者没有查看原生驱动名称,可以通过lspci查看详细信息获得

lspci -vs 03:00.0 
03:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (4*25GE) (rev 45)
        Subsystem: Huawei Technologies Co., Ltd. Device d136
        Flags: fast devsel, NUMA node 0
        Memory at 80003d00000 (64-bit, prefetchable) [size=128K]
        Memory at 800044a0000 (64-bit, prefetchable) [size=32K]
        [virtual] Memory at 80000000000 (64-bit, prefetchable) [size=1M]
        Expansion ROM at e9000000 [disabled] [size=1M]
        Capabilities: [40] Express Endpoint, MSI 00
        Capabilities: [80] MSI: Enable- Count=1/32 Maskable+ 64bit+
        Capabilities: [a0] MSI-X: Enable- Count=32 Masked-
        Capabilities: [b0] Power Management version 3
        Capabilities: [c0] Vital Product Data
        Capabilities: [100] Advanced Error Reporting
        Capabilities: [150] Alternative Routing-ID Interpretation (ARI)
        Capabilities: [200] Single Root I/O Virtualization (SR-IOV)
        Capabilities: [310] Secondary PCI Express <?>
        Capabilities: [4e0] Device Serial Number cc-05-77-ff-ff-ae-71-37
        Capabilities: [4f0] Transaction Processing Hints
        Capabilities: [600] Vendor Specific Information: ID=0000 Rev=0 Len=028 <?>
        Capabilities: [630] Access Control Services
        Kernel driver in use: igb_uio
        Kernel modules: hinic

最后两行,Kernel driver in use是当前使用的驱动,Kernel moddules对应着原生驱动

iommu

./dpdk-helloworld  
EAL: Detected 96 lcore(s)
EAL: Detected 4 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: Probing VFIO support...
EAL: PCI device 0000:03:00.0 on NUMA socket 0
EAL:   probe driver: 19e5:1822 net_hinic
net_hinic: API CMD poll status timeout
net_hinic: chain type: 0x7
net_hinic: chain hw cpld error: 0x1
net_hinic: chain hw check error: 0x0
net_hinic: chain hw current fsm: 0x0
net_hinic: chain hw current ci: 0x0
net_hinic: Chain hw current pi: 0x1
net_hinic: Send msg to mgmt failed
net_hinic: Failed to get board info, err: -110, status: 0x0, out size: 0x0
net_hinic: Check card workmode failed, dev_name: 0000:03:00.0
net_hinic: Create nic device failed, dev_name: 0000:03:00.0
net_hinic: Initialize 0000:03:00.0 in primary failed
EAL: Requested device 0000:03:00.0 cannot be used

如果运行dpdk的时候报上面的错误,那是因为开启了IOMMU,相关信息可以参考华为官网资料鲲鹏BoostKit虚拟化使能套件 OVS流表归一化 特性指南 07
配置方法,在/etc/grub2-efi.cfg中,在开机启动项一行最后增加iommu.passthrough=1,绕过IOMMU。IOMMU是用于另外一种驱动方式vfio,需要软硬件支持。

linux   /vmlinuz-4.19.90-2003.4.0.0036.oe1.aarch64 root=/dev/mapper/openeuler-root ro rd.lvm.lv=openeuler/r    oot rd.lvm.lv=openeuler/swap video=VGA-1:640x480-32@60me  smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15 cra    shkernel=1024M,high video=efifb:off video=VGA-1:640x480-32@60me default_hugepagesz=2M hugepagesz=2M hugepages=128 i    ommu.passthrough=1

iommu.passthrough

iommu.passthrough=
		[ARM64, X86] Configure DMA to bypass the IOMMU by default.
		Format: { "0" | "1" }
		0 - Use IOMMU translation for DMA.
		1 - Bypass the IOMMU for DMA.
		unset - Use value of CONFIG_IOMMU_DEFAULT_PASSTHROUGH.

如果用vfio,需要开启iommu,配置为在上面开机启动项最后增加iommu=pt intel_iommu=on

查看是否开启iommu

cat /proc/cmdline

查看cmdline相关信息是否有iommu=ptintel_iommu=on
https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/kernel-parameters.txt

使用vfio驱动

确保cpu支持VT-xVT-d,并且BIOS也打开了相关配置。

配置grub

     linux   /vmlinuz-4.19.90-2003.4.0.0036.oe1.x86_64 root=/dev/mapper/openeuler-root ro resume=/dev/ma    pper/openeuler-swap rd.lvm.lv=openeuler/root rd.lvm.lv=openeuler/swap rhgb quiet quiet crashkernel=512M     iommu=pt intel_iommu=on 

增加iommu=pt intel_iommu=on,打开iommu,重启系统

加载驱动

modprobe vfio
modprobe vfio-pci

绑定网卡

bin/dpdk-devbind.py -b vfio-pci 0000:84:00.0

查看网卡信息

bin/dpdk-devbind.py -s

Network devices using DPDK-compatible driver
============================================
0000:84:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' drv=vfio-pci unused=ixgbe

Network devices using kernel driver
===================================
0000:05:00.0 'I350 Gigabit Network Connection 1521' if=enp5s0f0 drv=igb unused=vfio-pci *Active*
0000:05:00.1 'I350 Gigabit Network Connection 1521' if=enp5s0f1 drv=igb unused=vfio-pci 
0000:84:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection 10fb' if=enp132s0f1 drv=ixgbe unused=vfio-pci
posted @ 2023-02-15 17:53  秋来叶黄  阅读(1347)  评论(0编辑  收藏  举报