在qemu中配置pci bus和numa node亲和性
在多numa node的物理机中,pci bus常常是连接到其中一个numa上。如此,不同的numa节点访问该pci bus下的设备的访问速度是不同的。基于此常常要将访问该设备的负载绑定到对应的numa node上可以提供性能。
对于qemu虚拟机也可以模拟pci bus与numa之间的亲和性。在x86机器中,只有pxb和pxb-pcie总线支持设置numa节点。其中pxb只能在i440fxx上使用,pxb-pcie可以在q35中使用。对于pcie总线:
pxb-pcie是挂在pcie.0上的,表示另一根主桥。下面是一个示例:
qemu-system-x86_64 --enable-kvm -M q35 \ -monitor unix:qemu-monitor-socket,server,nowait \ -serial mon:stdio \ -m 10G \ -smp 16,maxcpus=20 \ -boot a \ -object memory-backend-ram,id=ram-node0,size=5G,host-nodes=2,policy=bind \ -numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \ -object memory-backend-ram,id=ram-node1,size=5G,host-nodes=3,policy=bind \ -numa node,nodeid=1,cpus=8-15,memdev=ram-node1 \ -device pxb-pcie,id=pcie.1,bus=pcie.0,addr=0x3,numa_node=0,bus_nr=5 \ -device pcie-root-port,port=0x10,chassis=1,id=pci.1,bus=pcie.1,multifunction=on,addr=0x2 \ -device pcie-root-port,port=0x11,chassis=2,id=pci.2,bus=pcie.1,addr=0x2.0x1 \ -device pcie-root-port,port=0x12,chassis=3,id=pci.3,bus=pcie.1,addr=0x2.0x2 \ -device pcie-root-port,port=0x13,chassis=4,id=pci.4,bus=pcie.1,addr=0x2.0x3 \ -device pcie-root-port,port=0x13,chassis=5,id=pci.5,bus=pcie.1,addr=0x2.0x4 \ -device pcie-pci-bridge,id=pcie-pci-br0,bus=pcie.1 \ -device virtio-blk-pci,scsi=off,bus=pcie-pci-br0,addr=0x1,drive=hd1,id=virtio-disk0,bootindex=1 \ -drive if=none,file=jammy-server-cloudimg-amd64.img,id=hd1 \
在上例中,pxb-pcie挂在pcie.0上,设备不能直接挂在pxb上,必须先创建pci bridge或者pcie root port,然后将设备挂在pci桥或者pcie root port上。在pxb-pcie的参数中有一项是我们关心的,那就是numa_node。设置了这个就可以在guest中看到pxb下面的桥和设备跟numa的连接关系。
虚拟机起来后,我们可以使用lstopo看pci和numa的关系。
# lspci 00:00.0 Host bridge: Intel Corporation 82G33/G31/P35/P31 Express DRAM Controller 00:03.0 Host bridge: Red Hat, Inc. QEMU PCIe Expander bridge 00:1f.0 ISA bridge: Intel Corporation 82801IB (ICH9) LPC Interface Controller (rev 02) 00:1f.2 SATA controller: Intel Corporation 82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode] (rev 02) 00:1f.3 SMBus: Intel Corporation 82801I (ICH9 Family) SMBus Controller (rev 02) 05:00.0 PCI bridge: Red Hat, Inc. Device 000e 05:02.0 PCI bridge: Red Hat, Inc. QEMU PCIe Root port 05:02.1 PCI bridge: Red Hat, Inc. QEMU PCIe Root port 05:02.2 PCI bridge: Red Hat, Inc. QEMU PCIe Root port 05:02.3 PCI bridge: Red Hat, Inc. QEMU PCIe Root port 05:02.4 PCI bridge: Red Hat, Inc. QEMU PCIe Root port 06:01.0 SCSI storage controller: Red Hat, Inc. Virtio block device 08:00.0 SCSI storage controller: Red Hat, Inc. Virtio block device (rev 01) 09:00.0 SCSI storage controller: Red Hat, Inc. Virtio block device (rev 01) 0a:00.0 Unclassified device [00ff]: Red Hat, Inc. Virtio RNG (rev 01) 0b:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
lstopo
可以看到pxb-pcie下面的设备都连接到了numa0,跟设置是一致的。
这里有一个疑问,虽然pxb-pcie下面的桥和设备都连接到了numa0,但是pxb-pcie本身却没有任何numa信息。pcie.0主桥没办法连接到numa 节点,在guest kernel启动中报了warning:
[ 0.815158] PCI host bridge to bus 0000:00 [ 0.816043] pci_bus 0000:00: Unknown NUMA node; performance will be reduced