2

我打算在笔记本电脑上开发一个DPDK Linux 应用程序,但是 DPDK 不支持笔记本电脑的硬件。幸运的是,DPDK支持半虚拟化设备,包括QEMUvirtio-net.

所以我正在尝试配置一个 QEMU 来宾以在设备上运行内核 NIC 接口(KNI)virtio-net-pci。问题是 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.

问题

甚至可以使用设备运行KNI吗?virtio-net-pci

如果不可能,是否有其他选择可以在虚拟化环境中开发DPDK KNI应用程序?

4

2 回答 2

2

virtio_read_caps()无法映射 PCI 设备,因为 DPDK 需要将网络端口绑定到以下内核模块之一:

  • uio_pci_generic,
  • igb_uio,
  • vfio-pci

从 1.4 版开始,DPDK 应用程序不再自动解除所有支持的网络端口与正在使用的内核驱动程序的绑定。相反,DPDK 应用程序要使用的所有端口都必须在应用程序运行之前绑定到uio_pci_genericigb_uiovfio-pci模块。Linux* 控制下的任何网络端口都将被 DPDK 轮询模式驱动程序忽略,并且不能被应用程序使用。

因此,在运行 DPDK KNI 应用程序之前,我们应该

  1. 加载至少一个受支持的 I/O 内核模块uio_pci_genericigb_uiovfio-pci
  2. 加载$RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko
  3. 通过$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 目标环境目录。
于 2016-06-05T16:43:50.267 回答
1

我很确定-netdev user它与您想要的不兼容,因为它传递的是 TCP 数据而不是整个以太网帧。根据http://wiki.qemu.org/Documentation/Networking

用户网络是使用“slirp”实现的,它在 QEMU 中提供了一个完整的 TCP/IP 堆栈,并使用该堆栈来实现一个虚拟的 NAT'd 网络。

您希望您的选项更像http://www.dpdk.org/doc/guides/nics/virtio.html中指定的选项

-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
于 2016-06-04T04:50:51.993 回答