0. 目录
1. 垫话
2. 前言
3. 环境搭建
3.1 要求
-
一台运行 linux 发行版的计算机。本手册基于 CentOS7,但文中所涉及命令在其他 linux 发行版上应该不会有太大的变化,尤其是 Red Hat Enterprise Linux 7。 -
一个有 sudo 权限的账户。 -
home 目录下至少有 25G 可用空间。 -
至少 8G 的 RAM。
sudo yum install qemu-kvm libvirt-daemon-qemu libvirt-daemon-kvm libvirt virt-install libguestfs-tools-c kernel-tools dpdk dpdk-tools
3.2 创建 VM
user@host $ sudo wget -O /var/lib/libvirt/images/CentOS-7-x86_64-GenericCloud.qcow2 http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2
uservar/lib/libvirt/images/CentOS-7-x86_64-GenericCloud.qcow2 /var/lib/libvirt/images//vhuser-test1.qcow2 20G $ sudo qemu-img create -f qcow2 -b /
userexport LIBVIRT_DEFAULT_URI="qemu:///system" $
user@host $ sudo virt-sysprep --root-password password:changeme --uninstall cloud-init --selinux-relabel -a /var/lib/libvirt/images/vhuser-test1.qcow2 --network --install “dpdk,dpdk-tools,pciutils”
userdefault.xml $ virsh net-define /usr/share/libvirt/networks/
Network default defined from /usr/share/libvirt/networks/default.xml
userdefault $ virsh net-start
Network default started
user $virsh net-list
Name State Autostart Persistent
--------------------------------------------
default active no yes
user@host $ virt-install --import --name vdpa-test1 --ram=5120 --vcpus=3
--nographics --accelerate --machine q35
--network network:default,model=virtio --mac 02:ca:fe:fa:ce:aa
--debug --wait 0 --console pty
--disk /var/lib/libvirt/images/vdpa-test1.qcow2,bus=virtio --os-variant centos7.0
$ virsh list
Id Name State
------------------------------
1 vdpa-test1 running
user@host $ virsh shutdown vdpa-test1
3.3 准备 host
user@host $ sudo grubby --args=“default_hugepagesz=1G hugepagesz=1G hugepages=6” --update-kernel /boot/<your kernel image file>
-
default_hugepagesz=1G:指定默认创建 1G 大页。 -
hugepagesz=1G:指定启动阶段创建 1G 大页。 -
hugepagesz=6:初始时创建 6 个大页(每个 1G)。该信息启动后可通过 /proc/meminfo 查看。
user@host $ cat /proc/cmdline
3.4 准备 guest
user@host $ virsh edit vdpa-test1
<controller type='pci' index='8' model='pcie-root-port'>
<model name='pcie-root-port'/>
<target chassis='8' port='0xe'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</controller>
<interface type='vhostuser'>
<mac address='52:54:00:58:d7:01'/>
<source type='unix' path='/tmp/vhost-user1' mode='client'/>
<model type='virtio'/>
<driver name='vhost' rx_queue_size='256' iommu='on' ats='on'/>
<address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0'/>
</interface>
最后,添加 IOMMU 设备,并使能中断重映射及 IOTLB 支持:
<iommu model='intel'>
<driver intremap='on' iotlb='on'/>
</iommu>
<memoryBacking>
<hugepages>
<page size='1048576' unit='KiB' nodeset='0'/>
</hugepages>
<locked/>
</memoryBacking>
<numatune>
<memory mode='strict' nodeset='0'/>
</numatune>
为了让 vhost-user 后端可以访问内存,我们需要在 guest 配置中添加额外设置。这很重要,没有它我们将看不到任何被传输的 packets:
<cpu mode='host-passthrough' check='none'>
<topology sockets='1' cores='3' threads='1'/>
<numa>
<cell id='0' cpus='0-2' memory=’5242880’ unit='KiB' memAccess='shared'/>
</numa>
</cpu>
<features>
<acpi/>
<apic/>
<ioapic driver='qemu'/>
</features>
user@host $ sudo testpmd -l 0,2 --socket-mem=1024 -n 4
--vdev 'net_vhost0,iface=/tmp/vhost-user1,iommu-support=1' --
--portmask=1 -i --rxq=1 --txq=1
--nb-cores=1 --forward-mode=io
user@host $ virsh start vdpa-test1
root@guest $ sudo grubby --args=“default_hugepagesz=1G hugepagesz=1G hugepages=2 intel_iommu=on iommu=pt” --update-kernel /boot/<your kernel image file>
如此,新的内核参数已设置好,重启 guest。
root@guest $ modprobe vfio-pci
找到 virtio-net 设备的 PCI 地址:
root@guest $ dpdk-devbind --status net
…
Network devices using kernel driver
===================================
0000:01:00.0 'Virtio network device 1041' if=eth0 drv=virtio-pci unused=virtio_pci,vfio-pci *Active*
0000:08:00.0 'Virtio network device 1041' if=eth1 drv=virtio-pci unused=virtio_pci,vfio-pci
dpdk-devbind 输出中找到没有标记 “Active” 的项,可以使用它们来做实验。
root@guests $ dpdk-devbind.py -b vfio-pci 0000:08:00.0
root@guests $ testpmd -l 0,1 --socket-mem 1024 -n 4 -- --portmask=1 -i --auto-start
然后我们可以在 host testpmd 实例中开始数据包转发,在 IO 转发 loop 中注入 packets burst:
HOST testpmd> start tx_first 512
为了检查这一切是否正常工作,我们可以通过重复调用 show port stats all 命令来检查任一 testpmd 实例中的端口统计信息:
HOST testpmd> show port stats all
####################### NIC statistics for port 0 ########################
RX-packets: 60808544 RX-missed: 0 RX-bytes: 3891746816
RX-errors: 0
RX-nombuf: 0
TX-packets: 60824928 TX-errors: 0 TX-bytes: 3892795392
Throughput (since last show)
Rx-pps: 12027830
Tx-pps: 12027830
###########################################################################
4. 创建 accelerated data path
4.1 构建 vDPA 应用
root@guests $ yum install git gcc numactl-devel kernel-devel
然后,构建 DPDK 库:
root//gitlab.com/mcoquelin/dpdk-next-virtio.git dpdk $ git clone https:
root $ cd dpdk
root $ git checkout remotes/origin/virtio_vdpa_v1
rootexport RTE_SDK=`pwd` $
rootexport RTE_TARGET=x86_64-native-linuxapp-gcc $
root $ make -j2 install T=$RTE_TARGET DESTDIR=install
最后,我们构建 DPDK 目录中的 vDPA 示例程序。此应用将 probe vDPA 驱动,并通过 vDPA 框架将 vDPA 设备绑定到一个 vhost-user socket:
root@guests $ cd examples/vdpa
root@guests $ make
4.2 启动 vDPA 应用
root@guests $ dpdk-devbind.py -b vfio-pci 0000:08:00.0
$ ./build/vdpa -l 0,2 --socket-mem 1024 -w 0000:08:00.0,vdpa=1 -- --iface /tmp/vdpa
EAL: Detected 3 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: Probing VFIO support...
EAL: VFIO support initialized
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using unreliable clock cycles !
EAL: PCI device 0000:08:00.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 1af4:1041 net_virtio
EAL: PCI device 0000:08:00.0 on NUMA socket 0
EAL: probe driver: 1af4:1041 net_virtio_vdpa
EAL: using IOMMU type 1 (Type 1)
iface /tmp/vdpa
VHOST_CONFIG: vhost-user server: socket created, fd: 27
VHOST_CONFIG: bind to /tmp/vdpa0
enter 'q' to quit
4.3 启动用户应用
root@guests $ ./install/bin/testpmd -l 0,2 --socket-mem 1024 --file-prefix=virtio-user --no-pci --vdev=net_virtio_user0,path=/tmp/vdpa0
HOST testpmd> start tx_first 512
HOST testpmd> show port stats all
######################## NIC statistics for port 0 ########################
3565442688 RX-missed: 0 RX-bytes: 228188332032 :
0 :
0 :
3565459040 TX-errors: 0 TX-bytes: 228189378560 :
Throughput (since last show)
11997065 :
11997065 :
############################################################################
5. 结论
原文始发于微信公众号(窗有老梅):[译 10] vDPA 实操