1decb35d8SBruce Richardson.. SPDX-License-Identifier: BSD-3-Clause 2decb35d8SBruce Richardson Copyright(c) 2016 Intel Corporation. 3decb35d8SBruce Richardson 4decb35d8SBruce Richardson.. _virtio_user_as_exception_path: 5decb35d8SBruce Richardson 6decb35d8SBruce RichardsonVirtio_user as Exception Path 7decb35d8SBruce Richardson============================= 8decb35d8SBruce Richardson 9decb35d8SBruce Richardson.. note:: 10decb35d8SBruce Richardson 11decb35d8SBruce Richardson This solution is only applicable to Linux systems. 12decb35d8SBruce Richardson 13decb35d8SBruce RichardsonThe virtual device, virtio-user, was originally introduced with the vhost-user 14decb35d8SBruce Richardsonbackend as a high performance solution for IPC (Inter-Process Communication) 15decb35d8SBruce Richardsonand user space container networking. 16decb35d8SBruce Richardson 17decb35d8SBruce RichardsonBeyond this originally intended use, 18decb35d8SBruce Richardsonvirtio-user can be used in conjunction with the vhost-kernel backend 19decb35d8SBruce Richardsonas a solution for dealing with exception path packets 20decb35d8SBruce Richardsonwhich need to be injected into the Linux kernel for processing there. 21decb35d8SBruce RichardsonIn this regard, virtio-user and vhost in kernel space are an alternative to DPDK KNI 22decb35d8SBruce Richardsonfor transferring packets between a DPDK packet processing application and the kernel stack. 23decb35d8SBruce Richardson 24decb35d8SBruce RichardsonThis solution has a number of advantages over alternatives such as KNI: 25decb35d8SBruce Richardson 26decb35d8SBruce Richardson* Maintenance 27decb35d8SBruce Richardson 28decb35d8SBruce Richardson All kernel modules needed by this solution, vhost and vhost-net (kernel), 29decb35d8SBruce Richardson are upstreamed and extensively used. 30decb35d8SBruce Richardson 31decb35d8SBruce Richardson* Features 32decb35d8SBruce Richardson 33decb35d8SBruce Richardson vhost-net is designed to be a networking solution, and, as such, 34decb35d8SBruce Richardson has lots of networking related features, 35decb35d8SBruce Richardson such as multi queue support, TSO, multi-segment buffer support, etc. 36decb35d8SBruce Richardson 37decb35d8SBruce Richardson* Performance 38decb35d8SBruce Richardson 39decb35d8SBruce Richardson Similar to KNI, this solution would use one or more kthreads 40decb35d8SBruce Richardson to send/receive packets to/from user space DPDK applications, 41decb35d8SBruce Richardson which minimises the impact on the polling DPDK threads. 42decb35d8SBruce Richardson 43decb35d8SBruce RichardsonThe overview of an application using virtio-user as exception path is shown 44decb35d8SBruce Richardsonin :numref:`figure_virtio_user_as_exception_path`. 45decb35d8SBruce Richardson 46decb35d8SBruce Richardson.. _figure_virtio_user_as_exception_path: 47decb35d8SBruce Richardson 48decb35d8SBruce Richardson.. figure:: img/virtio_user_as_exception_path.* 49decb35d8SBruce Richardson 50decb35d8SBruce Richardson Overview of a DPDK app using virtio-user as exception path 51decb35d8SBruce Richardson 52decb35d8SBruce Richardson 53decb35d8SBruce RichardsonExample Usage With Testpmd 54decb35d8SBruce Richardson--------------------------- 55decb35d8SBruce Richardson 56decb35d8SBruce Richardson.. note:: 57decb35d8SBruce Richardson 58decb35d8SBruce Richardson These instructions assume that the vhost/vhost-net kernel modules are available 59decb35d8SBruce Richardson and have already been loaded into the running kernel. 60decb35d8SBruce Richardson It also assumes that the DPDK virtio driver has not been disabled in the DPDK build. 61decb35d8SBruce Richardson 62decb35d8SBruce RichardsonTo run a simple test of virtio-user as exception path using testpmd: 63decb35d8SBruce Richardson 64decb35d8SBruce Richardson#. Compile DPDK and bind a NIC to vfio-pci as documented in :ref:`linux_gsg_linux_drivers`. 65decb35d8SBruce Richardson 66decb35d8SBruce Richardson This physical NIC is for communicating with the outside world, 67decb35d8SBruce Richardson and serves as a packet source in this example. 68decb35d8SBruce Richardson 69decb35d8SBruce Richardson#. Run testpmd to forward packets from NIC to kernel, 70decb35d8SBruce Richardson passing in a suitable list of logical cores to run on (``-l`` parameter), 71decb35d8SBruce Richardson and optionally the PCI address of the physical NIC to use (``-a`` parameter). 72decb35d8SBruce Richardson The virtio-user device for interfacing to the kernel is specified via a ``--vdev`` argument, 73decb35d8SBruce Richardson taking the parameters described below. 74decb35d8SBruce Richardson 75decb35d8SBruce Richardson .. code-block:: console 76decb35d8SBruce Richardson 77decb35d8SBruce Richardson /path/to/dpdk-testpmd -l <cores> -a <pci BDF> \ 78decb35d8SBruce Richardson --vdev=virtio_user0,path=/dev/vhost-net,queues=1,queue_size=1024 79decb35d8SBruce Richardson 80decb35d8SBruce Richardson ``path`` 81decb35d8SBruce Richardson The path to the kernel vhost-net device. 82decb35d8SBruce Richardson 83decb35d8SBruce Richardson ``queue_size`` 84decb35d8SBruce Richardson 256 by default. To avoid shortage of descriptors, we can increase it to 1024. 85decb35d8SBruce Richardson 86decb35d8SBruce Richardson ``queues`` 87decb35d8SBruce Richardson Number of virt-queues. Each queue will be served by a kthread. 88decb35d8SBruce Richardson 89decb35d8SBruce Richardson#. Once testpmd is running, a new network interface - called ``tap0`` by default - 90decb35d8SBruce Richardson will be present on the system. 91decb35d8SBruce Richardson This should be configured with an IP address and then enabled for use: 92decb35d8SBruce Richardson 93decb35d8SBruce Richardson .. code-block:: console 94decb35d8SBruce Richardson 95decb35d8SBruce Richardson ip addr add 192.168.1.1/24 dev tap0 96decb35d8SBruce Richardson ip link set dev tap0 up 97decb35d8SBruce Richardson 98decb35d8SBruce Richardson#. To observe packet forwarding through the kernel, 99decb35d8SBruce Richardson a second testpmd instance can be run on the system, 100decb35d8SBruce Richardson taking packets from the kernel using an ``af_packet`` socket on the ``tap0`` interface. 101decb35d8SBruce Richardson 102decb35d8SBruce Richardson .. code-block:: console 103decb35d8SBruce Richardson 104decb35d8SBruce Richardson /path/to/dpdk-testpmd -l <cores> --vdev=net_af_packet0,iface=tap0 --in-memory --no-pci 105decb35d8SBruce Richardson 106decb35d8SBruce Richardson When running this instance, 107decb35d8SBruce Richardson we can use ``--in-memory`` flag to avoid hugepage naming conflicts with the previous instance, 108decb35d8SBruce Richardson and we also use ``--no-pci`` flag to only use the ``af_packet`` interface 109decb35d8SBruce Richardson for all traffic forwarding. 110decb35d8SBruce Richardson 111decb35d8SBruce Richardson#. Running traffic into the system through the NIC should see that traffic returned back again, 112decb35d8SBruce Richardson having been forwarded through both testpmd instances. 113decb35d8SBruce Richardson This can be confirmed by checking the testpmd statistics on testpmd exit. 114decb35d8SBruce Richardson 115decb35d8SBruce RichardsonFor more advanced use of virtio-user with testpmd in this scenario, 116decb35d8SBruce Richardsonsome other more advanced options may also be used. 117decb35d8SBruce RichardsonFor example: 118decb35d8SBruce Richardson 119decb35d8SBruce Richardson* ``--tx-offloads=0x02c`` 120decb35d8SBruce Richardson 121decb35d8SBruce Richardson This testpmd option enables Tx offloads for UDP and TCP checksum on transmit, 122decb35d8SBruce Richardson as well as TCP TSO support. 123decb35d8SBruce Richardson The list of the offload flag values can be seen in header 124decb35d8SBruce Richardson `rte_ethdev.h <https://doc.dpdk.org/api/rte__ethdev_8h.html>`_. 125decb35d8SBruce Richardson 126decb35d8SBruce Richardson* ``--enable-lro`` 127decb35d8SBruce Richardson 128decb35d8SBruce Richardson This testpmd option is used to negotiate VIRTIO_NET_F_GUEST_TSO4 and 129decb35d8SBruce Richardson VIRTIO_NET_F_GUEST_TSO6 feature so that large packets from the kernel can be 130decb35d8SBruce Richardson transmitted to the DPDK application and further TSOed by physical NIC. 131decb35d8SBruce Richardson If unsupported by the physical NIC, errors may be reported by testpmd with this option. 132decb35d8SBruce Richardson 133decb35d8SBruce Richardson* Enabling Rx checksum offloads for physical port: 134decb35d8SBruce Richardson 135decb35d8SBruce Richardson Within testpmd, you can enable and disable offloads on a per-port basis, 136decb35d8SBruce Richardson rather than enabling them for both ports. 137decb35d8SBruce Richardson For the physical NIC, it may be desirable to enable checksum offload on packet Rx. 138decb35d8SBruce Richardson This may be done as below, if testpmd is run with ``-i`` flag for interactive mode. 139decb35d8SBruce Richardson 140decb35d8SBruce Richardson .. code-block:: console 141decb35d8SBruce Richardson 142decb35d8SBruce Richardson testpmd> port stop 0 143decb35d8SBruce Richardson testpmd> port config 0 rx_offload tcp_cksum on 144decb35d8SBruce Richardson testpmd> port config 0 rx_offload udp_cksum on 145decb35d8SBruce Richardson testpmd> port start 0 146decb35d8SBruce Richardson 147decb35d8SBruce Richardson* Multiple queue support 148decb35d8SBruce Richardson 149decb35d8SBruce Richardson Better performance may be achieved by using multiple queues, 150decb35d8SBruce Richardson so that multiple kernel threads are handling the traffic on the kernel side. 151decb35d8SBruce Richardson For example, to use 2 queues on both NIC and virtio ports, 152decb35d8SBruce Richardson while also enabling TX offloads and LRO support: 153decb35d8SBruce Richardson 154decb35d8SBruce Richardson .. code-block:: console 155decb35d8SBruce Richardson 156decb35d8SBruce Richardson /path/to/dpdk-testpmd --vdev=virtio_user0,path=/dev/vhost-net,queues=2,queue_size=1024 -- \ 157decb35d8SBruce Richardson -i --tx-offloads=0x002c --enable-lro --txq=2 --rxq=2 --txd=1024 --rxd=1024 158decb35d8SBruce Richardson 159*99c58d23SBruce Richardson 160*99c58d23SBruce RichardsonCreating Virtio-User Ports within an Application 161*99c58d23SBruce Richardson------------------------------------------------ 162*99c58d23SBruce Richardson 163*99c58d23SBruce RichardsonTo use virtio-user ports within an application, 164*99c58d23SBruce Richardsonit is not necessary to explicitly initialize those ports using EAL arguments at startup. 165*99c58d23SBruce RichardsonInstead, one can use the generic EAL API 166*99c58d23SBruce Richardson`rte_eal_hotplug_add <https://doc.dpdk.org/api/rte__dev_8h.html#ad32e8eebf1f81ef9f290cb296b0c90bb>`_ 167*99c58d23SBruce Richardsonfunction to create a new instance at startup. 168*99c58d23SBruce RichardsonFor example, to create a basic virtio-user port, the following code could be used: 169*99c58d23SBruce Richardson 170*99c58d23SBruce Richardson.. code-block:: C 171*99c58d23SBruce Richardson 172*99c58d23SBruce Richardson rte_eal_hotplug_add("vdev", "virtio_user0", "path=/dev/vhost-net"); 173*99c58d23SBruce Richardson 174*99c58d23SBruce RichardsonA fuller code example is shown below, where a virtio-user port, and hence kernel netdev, 175*99c58d23SBruce Richardsonis created for each NIC port discovered by DPDK. 176*99c58d23SBruce RichardsonEach virtio-user port is given the MAC address of its matching physical port 177*99c58d23SBruce Richardson(assuming app was run without vdev args on command line, so all ports auto-discovered are HW ones). 178*99c58d23SBruce RichardsonThese new virtio-user netdevs will appear in the kernel port listings 179*99c58d23SBruce Richardsonas ``virtio_user0``, ``virtio_user1``, etc., 180*99c58d23SBruce Richardsonbased on the names passed in as ``iface=`` via the ``portargs`` parameter. 181*99c58d23SBruce Richardson 182*99c58d23SBruce Richardson.. code-block:: C 183*99c58d23SBruce Richardson 184*99c58d23SBruce Richardson nb_ports = rte_eth_dev_count_avail(); 185*99c58d23SBruce Richardson 186*99c58d23SBruce Richardson /* Create a vhost_user port for each physical port */ 187*99c58d23SBruce Richardson unsigned port_count = 0; 188*99c58d23SBruce Richardson RTE_ETH_FOREACH_DEV(portid) { 189*99c58d23SBruce Richardson char portname[32]; 190*99c58d23SBruce Richardson char portargs[256]; 191*99c58d23SBruce Richardson struct rte_ether_addr addr = {0}; 192*99c58d23SBruce Richardson 193*99c58d23SBruce Richardson /* once we have created a virtio port for each physical port, stop creating more */ 194*99c58d23SBruce Richardson if (++port_count > nb_ports) 195*99c58d23SBruce Richardson break; 196*99c58d23SBruce Richardson 197*99c58d23SBruce Richardson /* get MAC address of physical port to use as MAC of virtio_user port */ 198*99c58d23SBruce Richardson rte_eth_macaddr_get(portid, &addr); 199*99c58d23SBruce Richardson 200*99c58d23SBruce Richardson /* set the name and arguments */ 201*99c58d23SBruce Richardson snprintf(portname, sizeof(portname), "virtio_user%u", portid); 202*99c58d23SBruce Richardson snprintf(portargs, sizeof(portargs), 203*99c58d23SBruce Richardson "path=/dev/vhost-net,queues=1,queue_size=%u,iface=%s,mac=" RTE_ETHER_ADDR_PRT_FMT, 204*99c58d23SBruce Richardson RX_RING_SIZE, portname, RTE_ETHER_ADDR_BYTES(&addr)); 205*99c58d23SBruce Richardson 206*99c58d23SBruce Richardson /* add the vdev for virtio_user */ 207*99c58d23SBruce Richardson if (rte_eal_hotplug_add("vdev", portname, portargs) < 0) 208*99c58d23SBruce Richardson rte_exit(EXIT_FAILURE, "Cannot create paired port for port %u\n", portid); 209*99c58d23SBruce Richardson 210*99c58d23SBruce Richardson } 211*99c58d23SBruce Richardson 212*99c58d23SBruce RichardsonOnce these virtio-user ports have been created in the loop, 213*99c58d23SBruce Richardsonall ports, both physical and virtual, 214*99c58d23SBruce Richardsonmay be initialized and used as normal in the application. 215