netdev-dpdk: fix mbuf leaks
[cascardo/ovs.git] / INSTALL.DPDK.md
index 35dd9a0..1fc1b66 100644 (file)
@@ -16,7 +16,7 @@ OVS needs a system with 1GB hugepages support.
 Building and Installing:
 ------------------------
 
-Required: DPDK 2.0
+Required: DPDK 2.2
 Optional (if building with vhost-cuse): `fuse`, `fuse-devel` (`libfuse-dev`
 on Debian/Ubuntu)
 
@@ -24,7 +24,7 @@ on Debian/Ubuntu)
   1. Set `$DPDK_DIR`
 
      ```
-     export DPDK_DIR=/usr/src/dpdk-2.0
+     export DPDK_DIR=/usr/src/dpdk-2.2
      cd $DPDK_DIR
      ```
 
@@ -33,19 +33,14 @@ on Debian/Ubuntu)
 
      `CONFIG_RTE_BUILD_COMBINE_LIBS=y`
 
-     Update `config/common_linuxapp` so that DPDK is built with vhost
-     libraries.
-
-     `CONFIG_RTE_LIBRTE_VHOST=y`
-
      Then run `make install` to build and install the library.
      For default install without IVSHMEM:
 
-     `make install T=x86_64-native-linuxapp-gcc`
+     `make install T=x86_64-native-linuxapp-gcc DESTDIR=install`
 
      To include IVSHMEM (shared memory):
 
-     `make install T=x86_64-ivshmem-linuxapp-gcc`
+     `make install T=x86_64-ivshmem-linuxapp-gcc DESTDIR=install`
 
      For further details refer to http://dpdk.org/
 
@@ -65,7 +60,7 @@ on Debian/Ubuntu)
      `export DPDK_BUILD=$DPDK_DIR/x86_64-ivshmem-linuxapp-gcc/`
 
    ```
-   cd $(OVS_DIR)/openvswitch
+   cd $(OVS_DIR)/
    ./boot.sh
    ./configure --with-dpdk=$DPDK_BUILD [CFLAGS="-g -O2 -Wno-cast-align"]
    make
@@ -112,7 +107,7 @@ Using the DPDK with ovs-vswitchd:
      3. Bind network device to vfio-pci:
         `$DPDK_DIR/tools/dpdk_nic_bind.py --bind=vfio-pci eth1`
 
-3. Mount the hugetable filsystem
+3. Mount the hugetable filesystem
 
    `mount -t hugetlbfs -o pagesize=1G none /dev/hugepages`
 
@@ -173,9 +168,9 @@ Using the DPDK with ovs-vswitchd:
 
    `ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev`
 
-   Now you can add dpdk devices. OVS expect DPDK device name start with dpdk
-   and end with portid. vswitchd should print (in the log file) the number
-   of dpdk devices found.
+   Now you can add dpdk devices. OVS expects DPDK device names to start with
+   "dpdk" and end with a portid. vswitchd should print (in the log file) the
+   number of dpdk devices found.
 
    ```
    ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk0 type=dpdk
@@ -212,60 +207,246 @@ Using the DPDK with ovs-vswitchd:
    ./ovs-ofctl add-flow br0 in_port=2,action=output:1
    ```
 
-8. Performance tuning
+8. QoS usage example
 
-   With pmd multi-threading support, OVS creates one pmd thread for each
-   numa node as default.  The pmd thread handles the I/O of all DPDK
-   interfaces on the same numa node.  The following two commands can be used
-   to configure the multi-threading behavior.
+   Assuming you have a vhost-user port transmitting traffic consisting of
+   packets of size 64 bytes, the following command would limit the egress
+   transmission rate of the port to ~1,000,000 packets per second:
 
-   `ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=<hex string>`
+   `ovs-vsctl set port vhost-user0 qos=@newqos -- --id=@newqos create qos
+   type=egress-policer other-config:cir=46000000 other-config:cbs=2048`
 
-   The command above asks for a CPU mask for setting the affinity of pmd
-   threads.  A set bit in the mask means a pmd thread is created and pinned
-   to the corresponding CPU core.  For more information, please refer to
-   `man ovs-vswitchd.conf.db`
+   To examine the QoS configuration of the port:
 
-   `ovs-vsctl set Open_vSwitch . other_config:n-dpdk-rxqs=<integer>`
+   `ovs-appctl -t ovs-vswitchd qos/show vhost-user0`
 
-   The command above sets the number of rx queues of each DPDK interface. The
-   rx queues are assigned to pmd threads on the same numa node in round-robin
-   fashion.  For more information, please refer to `man ovs-vswitchd.conf.db`
+   To clear the QoS configuration from the port and ovsdb use the following:
 
-   Ideally for maximum throughput, the pmd thread should not be scheduled out
-   which temporarily halts its execution. The following affinitization methods
-   can help.
+   `ovs-vsctl destroy QoS vhost-user0 -- clear Port vhost-user0 qos`
 
-   Lets pick core 4,6,8,10 for pmd threads to run on.  Also assume a dual 8 core
-   sandy bridge system with hyperthreading enabled where CPU1 has cores 0,...,7
-   and 16,...,23 & CPU2 cores 8,...,15 & 24,...,31.  (A different cpu
-   configuration could have different core mask requirements).
+   For more details regarding egress-policer parameters please refer to the
+   vswitch.xml.
 
-   To kernel bootline add core isolation list for cores and associated hype cores
-   (e.g.  isolcpus=4,20,6,22,8,24,10,26,).  Reboot system for isolation to take
-   effect, restart everything.
+Performance Tuning:
+-------------------
 
-   Configure pmd threads on core 4,6,8,10 using 'pmd-cpu-mask':
+  1. PMD affinitization
 
-   `ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=00000550`
+       A poll mode driver (pmd) thread handles the I/O of all DPDK
+       interfaces assigned to it. A pmd thread will busy loop through
+       the assigned port/rxq's polling for packets, switch the packets
+       and send to a tx port if required. Typically, it is found that
+       a pmd thread is CPU bound, meaning that the greater the CPU
+       occupancy the pmd thread can get, the better the performance. To
+       that end, it is good practice to ensure that a pmd thread has as
+       many cycles on a core available to it as possible. This can be
+       achieved by affinitizing the pmd thread with a core that has no
+       other workload. See section 7 below for a description of how to
+       isolate cores for this purpose also.
 
-   You should be able to check that pmd threads are pinned to the correct cores
-   via:
+       The following command can be used to specify the affinity of the
+       pmd thread(s).
 
-   ```
-   top -p `pidof ovs-vswitchd` -H -d1
-   ```
+       `ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=<hex string>`
 
-   Note, the pmd threads on a numa node are only created if there is at least
-   one DPDK interface from the numa node that has been added to OVS.
+       By setting a bit in the mask, a pmd thread is created and pinned
+       to the corresponding CPU core. e.g. to run a pmd thread on core 1
+
+       `ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=2`
+
+       For more information, please refer to the Open_vSwitch TABLE section in
+
+       `man ovs-vswitchd.conf.db`
+
+       Note, that a pmd thread on a NUMA node is only created if there is
+       at least one DPDK interface from that NUMA node added to OVS.
+
+  2. Multiple poll mode driver threads
+
+       With pmd multi-threading support, OVS creates one pmd thread
+       for each NUMA node by default. However, it can be seen that in cases
+       where there are multiple ports/rxq's producing traffic, performance
+       can be improved by creating multiple pmd threads running on separate
+       cores. These pmd threads can then share the workload by each being
+       responsible for different ports/rxq's. Assignment of ports/rxq's to
+       pmd threads is done automatically.
+
+       The following command can be used to specify the affinity of the
+       pmd threads.
+
+       `ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=<hex string>`
+
+       A set bit in the mask means a pmd thread is created and pinned
+       to the corresponding CPU core. e.g. to run pmd threads on core 1 and 2
+
+       `ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=6`
+
+       For more information, please refer to the Open_vSwitch TABLE section in
+
+       `man ovs-vswitchd.conf.db`
+
+       For example, when using dpdk and dpdkvhostuser ports in a bi-directional
+       VM loopback as shown below, spreading the workload over 2 or 4 pmd
+       threads shows significant improvements as there will be more total CPU
+       occupancy available.
+
+       NIC port0 <-> OVS <-> VM <-> OVS <-> NIC port 1
+
+       The following command can be used to confirm that the port/rxq assignment
+       to pmd threads is as required:
+
+       `ovs-appctl dpif-netdev/pmd-rxq-show`
+
+       This can also be checked with:
+
+       ```
+       top -H
+       taskset -p <pid_of_pmd>
+       ```
+
+       To understand where most of the pmd thread time is spent and whether the
+       caches are being utilized, these commands can be used:
+
+       ```
+       # Clear previous stats
+       ovs-appctl dpif-netdev/pmd-stats-clear
+
+       # Check current stats
+       ovs-appctl dpif-netdev/pmd-stats-show
+       ```
+
+  3. DPDK port Rx Queues
+
+       `ovs-vsctl set Interface <DPDK interface> options:n_rxq=<integer>`
+
+       The command above sets the number of rx queues for DPDK interface.
+       The rx queues are assigned to pmd threads on the same NUMA node in a
+       round-robin fashion.  For more information, please refer to the
+       Open_vSwitch TABLE section in
+
+       `man ovs-vswitchd.conf.db`
+
+  4. Exact Match Cache
+
+       Each pmd thread contains one EMC. After initial flow setup in the
+       datapath, the EMC contains a single table and provides the lowest level
+       (fastest) switching for DPDK ports. If there is a miss in the EMC then
+       the next level where switching will occur is the datapath classifier.
+       Missing in the EMC and looking up in the datapath classifier incurs a
+       significant performance penalty. If lookup misses occur in the EMC
+       because it is too small to handle the number of flows, its size can
+       be increased. The EMC size can be modified by editing the define
+       EM_FLOW_HASH_SHIFT in lib/dpif-netdev.c.
+
+       As mentioned above an EMC is per pmd thread. So an alternative way of
+       increasing the aggregate amount of possible flow entries in EMC and
+       avoiding datapath classifier lookups is to have multiple pmd threads
+       running. This can be done as described in section 2.
+
+  5. Compiler options
+
+       The default compiler optimization level is '-O2'. Changing this to
+       more aggressive compiler optimizations such as '-O3' or
+       '-Ofast -march=native' with gcc can produce performance gains.
+
+  6. Simultaneous Multithreading (SMT)
+
+       With SMT enabled, one physical core appears as two logical cores
+       which can improve performance.
+
+       SMT can be utilized to add additional pmd threads without consuming
+       additional physical cores. Additional pmd threads may be added in the
+       same manner as described in section 2. If trying to minimize the use
+       of physical cores for pmd threads, care must be taken to set the
+       correct bits in the pmd-cpu-mask to ensure that the pmd threads are
+       pinned to SMT siblings.
+
+       For example, when using 2x 10 core processors in a dual socket system
+       with HT enabled, /proc/cpuinfo will report 40 logical cores. To use
+       two logical cores which share the same physical core for pmd threads,
+       the following command can be used to identify a pair of logical cores.
+
+       `cat /sys/devices/system/cpu/cpuN/topology/thread_siblings_list`
+
+       where N is the logical core number. In this example, it would show that
+       cores 1 and 21 share the same physical core. The pmd-cpu-mask to enable
+       two pmd threads running on these two logical cores (one physical core)
+       is.
+
+       `ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=100002`
+
+       Note that SMT is enabled by the Hyper-Threading section in the
+       BIOS, and as such will apply to the whole system. So the impact of
+       enabling/disabling it for the whole system should be considered
+       e.g. If workloads on the system can scale across multiple cores,
+       SMT may very beneficial. However, if they do not and perform best
+       on a single physical core, SMT may not be beneficial.
+
+  7. The isolcpus kernel boot parameter
+
+       isolcpus can be used on the kernel bootline to isolate cores from the
+       kernel scheduler and hence dedicate them to OVS or other packet
+       forwarding related workloads. For example a Linux kernel boot-line
+       could be:
+
+       'GRUB_CMDLINE_LINUX_DEFAULT="quiet hugepagesz=1G hugepages=4 default_hugepagesz=1G 'intel_iommu=off' isolcpus=1-19"'
+
+  8. NUMA/Cluster On Die
+
+       Ideally inter NUMA datapaths should be avoided where possible as packets
+       will go across QPI and there may be a slight performance penalty when
+       compared with intra NUMA datapaths. On Intel Xeon Processor E5 v3,
+       Cluster On Die is introduced on models that have 10 cores or more.
+       This makes it possible to logically split a socket into two NUMA regions
+       and again it is preferred where possible to keep critical datapaths
+       within the one cluster.
+
+       It is good practice to ensure that threads that are in the datapath are
+       pinned to cores in the same NUMA area. e.g. pmd threads and QEMU vCPUs
+       responsible for forwarding.
+
+  9. Rx Mergeable buffers
+
+       Rx Mergeable buffers is a virtio feature that allows chaining of multiple
+       virtio descriptors to handle large packet sizes. As such, large packets
+       are handled by reserving and chaining multiple free descriptors
+       together. Mergeable buffer support is negotiated between the virtio
+       driver and virtio device and is supported by the DPDK vhost library.
+       This behavior is typically supported and enabled by default, however
+       in the case where the user knows that rx mergeable buffers are not needed
+       i.e. jumbo frames are not needed, it can be forced off by adding
+       mrg_rxbuf=off to the QEMU command line options. By not reserving multiple
+       chains of descriptors it will make more individual virtio descriptors
+       available for rx to the guest using dpdkvhost ports and this can improve
+       performance.
+
+  10. Packet processing in the guest
+
+       It is good practice whether simply forwarding packets from one
+       interface to another or more complex packet processing in the guest,
+       to ensure that the thread performing this work has as much CPU
+       occupancy as possible. For example when the DPDK sample application
+       `testpmd` is used to forward packets in the guest, multiple QEMU vCPU
+       threads can be created. Taskset can then be used to affinitize the
+       vCPU thread responsible for forwarding to a dedicated core not used
+       for other general processing on the host system.
+
+  11. DPDK virtio pmd in the guest
+
+       dpdkvhostcuse or dpdkvhostuser ports can be used to accelerate the path
+       to the guest using the DPDK vhost library. This library is compatible with
+       virtio-net drivers in the guest but significantly better performance can
+       be observed when using the DPDK virtio pmd driver in the guest. The DPDK
+       `testpmd` application can be used in the guest as an example application
+       that forwards packet from one DPDK vhost port to another. An example of
+       running `testpmd` in the guest can be seen here.
+
+       `./testpmd -c 0x3 -n 4 --socket-mem 512 -- --burst=64 -i --txqflags=0xf00 --disable-hw-vlan --forward-mode=io --auto-start`
+
+       See below information on dpdkvhostcuse and dpdkvhostuser ports.
+       See [DPDK Docs] for more information on `testpmd`.
 
-   To understand where most of the time is spent and whether the caches are
-   effective, these commands can be used:
 
-   ```
-   ovs-appctl dpif-netdev/pmd-stats-clear #To reset statistics
-   ovs-appctl dpif-netdev/pmd-stats-show
-   ```
 
 DPDK Rings :
 ------------
@@ -315,7 +496,7 @@ the vswitchd.
 DPDK vhost:
 -----------
 
-DPDK 2.0 supports two types of vhost:
+DPDK 2.2 supports two types of vhost:
 
 1. vhost-user
 2. vhost-cuse
@@ -336,7 +517,7 @@ with OVS.
 DPDK vhost-user Prerequisites:
 -------------------------
 
-1. DPDK 2.0 with vhost support enabled as documented in the "Building and
+1. DPDK 2.2 with vhost support enabled as documented in the "Building and
    Installing section"
 
 2. QEMU version v2.1.0+
@@ -350,7 +531,8 @@ Adding DPDK vhost-user ports to the Switch:
 
 Following the steps above to create a bridge, you can now add DPDK vhost-user
 as a port to the vswitch. Unlike DPDK ring ports, DPDK vhost-user ports can
-have arbitrary names.
+have arbitrary names, except that forward and backward slashes are prohibited
+in the names.
 
   -  For vhost-user, the name of the port type is `dpdkvhostuser`
 
@@ -409,6 +591,41 @@ Follow the steps below to attach vhost-user port(s) to a VM.
    -numa node,memdev=mem -mem-prealloc
    ```
 
+3. Optional: Enable multiqueue support
+   The vhost-user interface must be configured in Open vSwitch with the
+   desired amount of queues with:
+
+   ```
+   ovs-vsctl set Interface vhost-user-2 options:n_rxq=<requested queues>
+   ```
+
+   QEMU needs to be configured as well.
+   The $q below should match the queues requested in OVS (if $q is more,
+   packets will not be received).
+   The $v is the number of vectors, which is '$q x 2 + 2'.
+
+   ```
+   -chardev socket,id=char2,path=/usr/local/var/run/openvswitch/vhost-user-2
+   -netdev type=vhost-user,id=mynet2,chardev=char2,vhostforce,queues=$q
+   -device virtio-net-pci,mac=00:00:00:00:00:02,netdev=mynet2,mq=on,vectors=$v
+   ```
+
+   If one wishes to use multiple queues for an interface in the guest, the
+   driver in the guest operating system must be configured to do so. It is
+   recommended that the number of queues configured be equal to '$q'.
+
+   For example, this can be done for the Linux kernel virtio-net driver with:
+
+   ```
+   ethtool -L <DEV> combined <$q>
+   ```
+
+   A note on the command above:
+
+   `-L`: Changes the numbers of channels of the specified network device
+
+   `combined`: Changes the number of multi-purpose channels.
+
 DPDK vhost-cuse:
 ----------------
 
@@ -418,7 +635,7 @@ with OVS.
 DPDK vhost-cuse Prerequisites:
 -------------------------
 
-1. DPDK 2.0 with vhost support enabled as documented in the "Building and
+1. DPDK 2.2 with vhost support enabled as documented in the "Building and
    Installing section"
    As an additional step, you must enable vhost-cuse in DPDK by setting the
    following additional flag in `config/common_linuxapp`:
@@ -721,17 +938,29 @@ Restrictions:
     this with smaller page sizes.
 
   Platform and Network Interface:
-  - Currently it is not possible to use an Intel XL710 Network Interface as a
-    DPDK port type on a platform with more than 64 logical cores. This is
-    related to how DPDK reports the number of TX queues that may be used by
-    a DPDK application with an XL710. The maximum number of TX queues supported
-    by a DPDK application for an XL710 is 64. If a user attempts to add an
-    XL710 interface as a DPDK port type to a system as described above the
-    port addition will fail as OVS will attempt to initialize a TX queue greater
-    than 64. This issue is expected to be resolved in a future DPDK release.
-    As a workaround a user can disable hyper-threading to reduce the overall
-    core count of the system to be less than or equal to 64 when using an XL710
-    interface with DPDK.
+  - By default with DPDK 2.2, a maximum of 64 TX queues can be used with an
+    Intel XL710 Network Interface on a platform with more than 64 logical
+    cores. If a user attempts to add an XL710 interface as a DPDK port type to
+    a system as described above, an error will be reported that initialization
+    failed for the 65th queue. OVS will then roll back to the previous
+    successful queue initialization and use that value as the total number of
+    TX queues available with queue locking. If a user wishes to use more than
+    64 queues and avoid locking, then the
+    `CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF` config parameter in DPDK must be
+    increased to the desired number of queues. Both DPDK and OVS must be
+    recompiled for this change to take effect.
+
+  vHost and QEMU v2.4.0+:
+  - For versions of QEMU v2.4.0 and later, it is currently not possible to
+    unbind more than one dpdkvhostuser port from the guest kernel driver
+    without causing the ovs-vswitchd process to crash. If this is a requirement
+    for your use case, it is recommended either to use a version of QEMU
+    between v2.2.0 and v2.3.1 (inclusive), or alternatively, to apply the
+    following patch to DPDK and rebuild:
+    http://dpdk.org/dev/patchwork/patch/7736/
+    This problem will likely be resolved in Open vSwitch at a later date, when
+    the next release of DPDK (which includes the above patch) is available and
+    integrated into OVS.
 
 Bug Reporting:
 --------------