我将在笔记本电脑上开发DPDK Linux应用程序,但DPDK不支持笔记本电脑的硬件。幸运的是,DPDK supports半虚拟化设备包括QEMU的virtio-net
。
所以我正在尝试配置QEMU来宾,以便在virtio-net-pci
设备上运行Kernel NIC Interface(KNI)。问题是KNI示例应用程序不接受virtio-net-pci
驱动程序。
QEMU命令
exec qemu-system-x86_64 -enable-kvm \
-cpu host -smp 2 \
-vga std \
-mem-prealloc -mem-path /dev/hugepages \
-drive file=GentooVM.img,if=virtio \
-netdev user,id=vmnic,hostname=gentoo \
-device virtio-net-pci,netdev=vmnic \
-m 1024M \
-monitor stdio \
-name "Gentoo VM"
在来宾中运行KNI示例应用
sudo ./examples/kni/build/app/kni -c 0x3 -n 4 -- \
-P -p 0x1 --config="(0,0,1)"
EAL: Detected lcore 0 as core 0 on socket 0
EAL: Detected lcore 1 as core 0 on socket 0
EAL: Support maximum 128 logical core(s) by configuration.
EAL: Detected 2 lcore(s)
EAL: Probing VFIO support...
EAL: IOMMU type 1 (Type 1) is supported
EAL: IOMMU type 8 (No-IOMMU) is not supported
EAL: VFIO support initialized
EAL: Setting up physically contiguous memory...
...
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using
unreliable clock cycles !
EAL: Master lcore 0 is ready (tid=657d58c0;cpuset=[0])
PMD: rte_igbvf_pmd_init(): >>
EAL: lcore 1 is ready (tid=305ff700;cpuset=[1])
EAL: PCI device 0000:00:03.0 on NUMA socket -1
EAL: probe driver: 1af4:1000 rte_virtio_pmd
EAL: Not managed by a supported kernel driver(0), skipped
PMD: virtio_read_caps(): failed to map pci device!
PMD: vtpci_init(): trying with legacy virtio pci.
Segmentation fault
在访客
中输出lspci
命令
...
00:03.0 Ethernet controller: Red Hat, Inc Virtio network device
我注意到pci_scan_one()
函数集dev->kdrv = RTE_KDRV_NONE
,而驱动程序被检测为virtio-pci
(来自/sys/bus/pci/devices/0000:00:03.0/driver
)。
TAP网络
TAP网络仍然存在同样的问题。在主机上,我从Wi-Fi接口配置了一个网桥,并将其连接到TAP接口:
wifi_iface=wlp3s0
br_iface=br0
br_network='172.20.0.1/16'
br_dhcp_range='172.20.0.2,172.20.255.254'
tap_iface=tap0
user=ruslan
ip link add name $br_iface type bridge
ip addr add "$br_network" dev $br_iface
ip link set $br_iface up
dnsmasq --interface=$br_iface --bind-interfaces \
--dhcp-range=$br_dhcp_range
modprobe tun
chmod 0666 /dev/net/tun
ip tuntap add dev $tap_iface mode tap user "$user"
ip link set $tap_iface up promisc on
ip link set $tap_iface master $br_iface
sysctl net.ipv4.ip_forward=1
sysctl net.ipv6.conf.default.forwarding=1
sysctl net.ipv6.conf.all.forwarding=1
iptables -t nat -A POSTROUTING -o $wifi_iface -j MASQUERADE
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $tap_iface -o $wifi_iface -j ACCEPT
QEMU命令:
sudo qemu-system-x86_64 -enable-kvm \
-cpu host -smp 2 \
-vga std \
-mem-prealloc -mem-path /dev/hugepages \
-drive file=GentooVM.img,if=virtio \
-netdev tap,id=vm1_p1,ifname=tap0,script=no,downscript=no,vhost=on \
-device virtio-net-pci,netdev=vm1_p1,bus=pci.0,addr=0x3,ioeventfd=on \
-m 1024M \
-monitor stdio \
-name "Gentoo VM" \
$@
来宾中输出 ifconfig
:
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.20.196.253 netmask 255.255.0.0 broadcast 172.20.255.255
inet6 fe80::59c1:f175:aeb3:433 prefixlen 64 scopeid 0x20<link>
ether 52:54:00:12:34:56 txqueuelen 1000 (Ethernet)
RX packets 9 bytes 1039 (1.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 21 bytes 1802 (1.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
以下命令的失败方式与上面“用户”网络的情况相同:
sudo ./examples/kni/build/app/kni -c 0x3 -n 4 -- \
-P -p 0x1 --config="(0,0,1)"
...
EAL: PCI device 0000:00:03.0 on NUMA socket -1
EAL: probe driver: 1af4:1000 rte_virtio_pmd
EAL: Not managed by a supported kernel driver(0), skipped
PMD: virtio_read_caps(): failed to map pci device!
PMD: vtpci_init(): trying with legacy virtio pci.
问题
是否可以使用virtio-net-pci
设备运行 KNI ?
如果不可能,还有其他选择在虚拟化环境中开发 DPDK KNI 应用程序吗?
答案 0 :(得分:2)
virtio_read_caps()
无法映射PCI设备,因为DPDK需要binding network ports到以下内核模块之一:
uio_pci_generic
,igb_uio
,vfio-pci
:从版本1.4开始,DPDK应用程序不再自动解除绑定 所有受支持的网络端口都来自正在使用的内核驱动代替, 必须绑定DPDK应用程序要使用的所有端口 申请前的
uio_pci_generic
,igb_uio
或vfio-pci
模块 运行。 Linux *控制下的任何网络端口都将被忽略 DPDK轮询模式驱动程序,不能被应用程序使用。
因此,在运行DPDK KNI应用程序之前,我们应该
uio_pci_generic
,igb_uio
或vfio-pci
)$RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko
$RTE_SDK/tools/dpdk_nic_bind.py
脚本将网络端口绑定到内核模块。例如:
$ sudo insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko
$ sudo insmod $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko
# Obtain ID of the network port
$ python2 $RTE_SDK/tools/dpdk_nic_bind.py --status
Network devices using DPDK-compatible driver
============================================
0000:00:03.0 'Virtio network device' drv=igb_uio unused=vfio-pci,uio_pci_generic
$ sudo python2 $RTE_SDK/tools/dpdk_nic_bind.py --bind=igb_uio 0000:00:03.0
,其中
$RTE_SDK
- 指向DPDK安装目录。$RTE_TARGET
- 指向DPDK目标环境目录。答案 1 :(得分:1)
我非常确定-netdev user
与您想要的内容不兼容,因为它传递的是TCP数据而不是整个以太网帧。根据{{3}}
用户网络是使用&#34; slirp&#34;实现的,它在QEMU中提供完整的TCP / IP堆栈,并使用该堆栈实现虚拟NAT网络。
您希望您的选项更像http://wiki.qemu.org/Documentation/Networking
中指定的选项-netdev tap,id=vm1_p1,ifname=tap0,script=no,vhost=on
-device virtio-net-pci,netdev=vm1_p1,bus=pci.0,addr=0x3,ioeventfd=on