Re: [PATCH v3 0/6] virtio,vhost: Add VIRTIO_F_IN_ORDER support
Jonah Palmer <[email protected]> Mon, 24 Jun 2024 10:57:41 -0400
| Newsgroups | dev.linux.lists.virtio-fs,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 6/20/24 2:40 PM, Eugenio Perez Martin wrote: > On Thu, Jun 20, 2024 at 7:56 PM Jonah Palmer <[email protected]> wrote: >> >> The goal of these patches is to add support to a variety of virtio and >> vhost devices for the VIRTIO_F_IN_ORDER transport feature. This feature >> indicates that all buffers are used by the device in the same order in >> which they were made available by the driver. >> >> These patches attempt to implement a generalized, non-device-specific >> solution to support this feature. >> >> The core feature behind this solution is a buffer mechanism in the form >> of a VirtQueue's used_elems VirtQueueElement array. This allows devices >> who always use buffers in-order by default to have a minimal overhead >> impact. Devices that may not always use buffers in-order likely will >> experience a performance hit. How large that performance hit is will >> depend on how frequently elements are completed out-of-order. >> >> A VirtQueue whose device uses this feature will use its used_elems >> VirtQueueElement array to hold used VirtQueueElements. The index that >> used elements are placed in used_elems is the same index on the >> used/descriptor ring that would satisfy the in-order requirement. In >> other words, used elements are placed in their in-order locations on >> used_elems and are only written to the used/descriptor ring once the >> elements on used_elems are able to continue their expected order. >> >> To differentiate between a "used" and "unused" element on the used_elems >> array (a "used" element being an element that has returned from >> processing and an "unused" element being an element that has not yet >> been processed), we added a boolean 'in_order_filled' member to the >> VirtQueueElement struct. This flag is set to true when the element comes >> back from processing (virtqueue_ordered_fill) and then set back to false >> once it's been written to the used/descriptor ring >> (virtqueue_ordered_flush). >> >> Testing: >> ======== >> Testing was done using the dpdk-testpmd application on both the host and >> guest using the following configurations. Traffic was generated between >> the host and guest after running 'start tx_first' on both the host and >> guest dpdk-testpmd applications. Results are below after traffic was >> generated for several seconds. >> >> Relevant Qemu args: >> ------------------- >> -chardev socket,id=char1,path=/tmp/vhost-user1,server=off >> -chardev socket,id=char2,path=/tmp/vhost-user2,server=off >> -netdev type=vhost-user,id=net1,chardev=char1,vhostforce=on,queues=1 >> -netdev type=vhost-user,id=net2,chardev=char2,vhostforce=on,queues=1 >> -device virtio-net-pci,in_order=true,packed=true,netdev=net1, >> mac=56:48:4f:53:54:00,mq=on,vectors=4,rx_queue_size=256 >> -device virtio-net-pci,in_order=true,packed=true,netdev=net2, >> mac=56:48:4f:53:54:01,mq=on,vectors=4,rx_queue_size=256 >> > > Hi Jonah, > > These tests are great, but others should also be performed. In > particular, QEMU should run ok with "tap" netdev with vhost=off > instead of vhost-user: > > -netdev type=tap,id=net1,vhost=off > -netdev type=tap,id=net2,vhost=off > > This way, packets are going through the modified code. With this > configuration, QEMU is the one forwarding the packets so testpmd is > not needed in the host. It's still needed in the guest as linux guest > driver does not support in_order. The guest kernel cmdline and testpmd > cmdline should require no changes from the configuration you describe > here. > Oof... I didn't even realize that my tests weren't actually testing all of the modified code. I was so focused on getting DPDK to work that I didn't think to check that. My apologies. I am running into some trouble though trying to get packets flowing in the guest. My Qemu args look like this: # Regular virtio-net device -device virtio-net-pci,netdev=net0,disable-legacy=off,disable-modern=off -netdev tap,id=net0,vhost=off,ifname=tap0,script=${QEMU_IFUP}, downscript=no # Virtio-net devices for testing -netdev type=tap,id=net1,vhost=off,ifname=tap1,script=no,downscript=no -netdev type=tap,id=net2,vhost=off,ifname=tap2,script=no,downscript=no -device virtio-net-pci,in_order=true,packed=true,netdev=net1, mac=56:48:4f:53:54:00,mq=on,vectors=4,rx_queue_size=256 -device virtio-net-pci,in_order=true,packed=true,netdev=net2, mac=56:48:4f:53:54:01,mq=on,vectors=4,rx_queue_size=256 In the guest I have the virtio-net devices I'm using for testing bound to the uio_pci_generic driver: dpdk-devbind.py --status net Network devices using DPDK-compatible driver ============================================ 0000:00:02.0 'Virtio network device 1000' drv=uio_pci_generic unused=virtio_pci,vfio-pci 0000:00:03.0 'Virtio network device 1000' drv=uio_pci_generic unused=virtio_pci,vfio-pci Network devices using kernel driver =================================== 0000:00:04.0 'Virtio network device 1000' if=enp0s4 drv=virtio-pci unused=virtio_pci,vfio-pci,uio_pci_generic *Active* But then after running the dpdk-testpmd command in the guest: dpdk-testpmd -l 0,1 -a 0000:00:02.0 -a 0000:00:03.0 -- --portmask=3 --rxq=1 --txq=1 --nb-cores=1 --forward-mode=io -i EAL: Detected CPU lcores: 6 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'PA' EAL: VFIO support initialized EAL: Probe PCI driver: net_virtio (1af4:1000) device: 0000:00:02.0 (socket -1) EAL: Probe PCI driver: net_virtio (1af4:1000) device: 0000:00:03.0 (socket -1) TELEMETRY: No legacy callbacks, legacy socket not created Set io packet forwarding mode Interactive-mode selected Warning: NUMA should be configured manually by using --port-numa-config and --ring-numa-config parameters along with --numa. testpmd: create a new mbuf pool <mb_pool_0>: n=155456, size=2176, socket=0 testpmd: preferred mempool ops selected: ring_mp_mc Configuring Port 0 (socket 0) Port 0: 56:48:4F:53:54:00 Configuring Port 1 (socket 0) Port 1: 56:48:4F:53:54:01 Checking link statuses... Done I'm not able to see any packets flowing after starting packet forwarding and running 'show port stats all': testpmd> start io packet forwarding - ports=2 - cores=1 - streams=2 - NUMA support enabled, MP allocation mode: native Logical Core 1 (socket 0) forwards packets on 2 streams: RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01 RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00 io packet forwarding packets/burst=32 nb forwarding cores=1 - nb forwarding ports=2 port 0: RX queue number: 1 Tx queue number: 1 Rx offloads=0x0 Tx offloads=0x0 RX queue: 0 RX desc=0 - RX free threshold=0 RX threshold registers: pthresh=0 hthresh=0 wthresh=0 RX Offloads=0x0 TX queue: 0 TX desc=0 - TX free threshold=0 TX threshold registers: pthresh=0 hthresh=0 wthresh=0 TX offloads=0x0 - TX RS bit threshold=0 port 1: RX queue number: 1 Tx queue number: 1 Rx offloads=0x0 Tx offloads=0x0 RX queue: 0 RX desc=0 - RX free threshold=0 RX threshold registers: pthresh=0 hthresh=0 wthresh=0 RX Offloads=0x0 TX queue: 0 TX desc=0 - TX free threshold=0 TX threshold registers: pthresh=0 hthresh=0 wthresh=0 TX offloads=0x0 - TX RS bit threshold=0 testpmd> testpmd> show port stats all ###### NIC statistics for port 0 ###### RX-packets: 0 RX-missed: 0 RX-bytes: 0 RX-errors: 0 RX-nombuf: 0 TX-packets: 0 TX-errors: 0 TX-bytes: 0 Throughput (since last show) Rx-pps: 0 Rx-bps: 0 Tx-pps: 0 Tx-bps: 0 ######################################################### ###### NIC statistics for port 1 ###### RX-packets: 0 RX-missed: 0 RX-bytes: 0 RX-errors: 0 RX-nombuf: 0 TX-packets: 0 TX-errors: 0 TX-bytes: 0 Throughput (since last show) Rx-pps: 0 Rx-bps: 0 Tx-pps: 0 Tx-bps: 0 ######################################################### I'm still working on improving my networking skills so I'm going to try and figure out what's going on here. Will let you know if I figure it out and check in with you to see if the test results are satisfactory before sending out a v4. > And then try with in_order=true,packed=false and > in_order=true,packed=off in corresponding virtio-net-pci. > > Performance comparison between in_order=true and in_order=false is > also interesting but we're not batching so I don't think we will get > an extreme improvement. > > Does the plan work for you? > > Thanks! > >> Host dpdk-testpmd command: >> -------------------------- >> dpdk-testpmd -l 0,2,3,4,5 --socket-mem=1024 -n 4 >> --vdev 'net_vhost0,iface=/tmp/vhost-user1' >> --vdev 'net_vhost1,iface=/tmp/vhost-user2' -- >> --portmask=f -i --rxq=1 --txq=1 --nb-cores=4 --forward-mode=io >> >> Guest dpdk-testpmd command: >> --------------------------- >> dpdk-testpmd -l 0,1 -a 0000:00:02.0 -a 0000:00:03.0 -- --portmask=3 >> --rxq=1 --txq=1 --nb-cores=1 --forward-mode=io -i >> >> Results: >> -------- >> +++++++++++++++ Accumulated forward statistics for all ports+++++++++++++++ >> RX-packets: 79067488 RX-dropped: 0 RX-total: 79067488 >> TX-packets: 79067552 TX-dropped: 0 TX-total: 79067552 >> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> >> --- >> v3: Drop Tested-by tags until patches are re-tested. >> Replace 'prev_avail_idx' with 'vq->last_avail_idx - 1' in >> virtqueue_split_pop. >> Remove redundant '+vq->vring.num' in 'max_steps' calculation in >> virtqueue_ordered_fill. >> Add test results to CV. >> >> v2: Make 'in_order_filled' more descriptive. >> Change 'j' to more descriptive var name in virtqueue_split_pop. >> Use more definitive search conditional in virtqueue_ordered_fill. >> Avoid code duplication in virtqueue_ordered_flush. >> >> v1: Move series from RFC to PATCH for submission. >> >> Jonah Palmer (6): >> virtio: Add bool to VirtQueueElement >> virtio: virtqueue_pop - VIRTIO_F_IN_ORDER support >> virtio: virtqueue_ordered_fill - VIRTIO_F_IN_ORDER support >> virtio: virtqueue_ordered_flush - VIRTIO_F_IN_ORDER support >> vhost,vhost-user: Add VIRTIO_F_IN_ORDER to vhost feature bits >> virtio: Add VIRTIO_F_IN_ORDER property definition >> >> hw/block/vhost-user-blk.c | 1 + >> hw/net/vhost_net.c | 2 + >> hw/scsi/vhost-scsi.c | 1 + >> hw/scsi/vhost-user-scsi.c | 1 + >> hw/virtio/vhost-user-fs.c | 1 + >> hw/virtio/vhost-user-vsock.c | 1 + >> hw/virtio/virtio.c | 123 ++++++++++++++++++++++++++++++++++- >> include/hw/virtio/virtio.h | 6 +- >> net/vhost-vdpa.c | 1 + >> 9 files changed, 134 insertions(+), 3 deletions(-) >> >> -- >> 2.43.0 >> >