xref: /dpdk/doc/guides/howto/virtio_user_as_exception_path.rst (revision 99c58d238d4a3d7969c94dac1a087d05e1ed14e3)
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