Building and Installing:
------------------------
-Required: DPDK 16.04
+Required: DPDK 16.04, libnuma
Optional (if building with vhost-cuse): `fuse`, `fuse-devel` (`libfuse-dev`
on Debian/Ubuntu)
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.
+ responsible for forwarding. If DPDK is built with
+ CONFIG_RTE_LIBRTE_VHOST_NUMA=y, vHost User ports automatically
+ detect the NUMA socket of the QEMU vCPUs and will be serviced by a PMD
+ from the same node provided a core on this node is enabled in the
+ pmd-cpu-mask.
9. Rx Mergeable buffers
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
+#include <numaif.h>
#include "dirs.h"
#include "dp-packet.h"
int requested_n_txq;
int requested_n_rxq;
+ /* Socket ID detected when vHost device is brought up */
+ int requested_socket_id;
+
/* Ingress Policer */
OVSRCU_TYPE(struct ingress_policer *) ingress_policer;
uint32_t policer_rate;
}
dev->socket_id = sid < 0 ? SOCKET0 : sid;
+ dev->requested_socket_id = dev->socket_id;
dev->port_id = port_no;
dev->type = type;
dev->flags = 0;
{
struct netdev_dpdk *dev;
bool exists = false;
+ int newnode = 0;
+ long err = 0;
ovs_mutex_lock(&dpdk_mutex);
/* Add device to the vhost port with the same name as that passed down. */
}
ovsrcu_set(&dev->virtio_dev, virtio_dev);
exists = true;
+
+ /* Get NUMA information */
+ err = get_mempolicy(&newnode, NULL, 0, virtio_dev,
+ MPOL_F_NODE | MPOL_F_ADDR);
+ if (err) {
+ VLOG_INFO("Error getting NUMA info for vHost Device '%s'",
+ virtio_dev->ifname);
+ newnode = dev->socket_id;
+ } else if (newnode != dev->socket_id) {
+ dev->requested_socket_id = newnode;
+ netdev_request_reconfigure(&dev->up);
+ }
+
virtio_dev->flags |= VIRTIO_DEV_RUNNING;
/* Disable notifications. */
set_irq_status(virtio_dev);
return -1;
}
- VLOG_INFO("vHost Device '%s' %"PRIu64" has been added", virtio_dev->ifname,
- virtio_dev->device_fh);
+ VLOG_INFO("vHost Device '%s' %"PRIu64" has been added on numa node %i",
+ virtio_dev->ifname, virtio_dev->device_fh, newnode);
return 0;
}
netdev_dpdk_vhost_user_reconfigure(struct netdev *netdev)
{
struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
+ int err = 0;
ovs_mutex_lock(&dpdk_mutex);
ovs_mutex_lock(&dev->mutex);
netdev->n_txq = dev->requested_n_txq;
netdev->n_rxq = dev->requested_n_rxq;
+ if (dev->requested_socket_id != dev->socket_id) {
+ dev->socket_id = dev->requested_socket_id;
+ /* Change mempool to new NUMA Node */
+ dpdk_mp_put(dev->dpdk_mp);
+ dev->dpdk_mp = dpdk_mp_get(dev->socket_id, dev->mtu);
+ if (!dev->dpdk_mp) {
+ err = ENOMEM;
+ }
+ }
+
ovs_mutex_unlock(&dev->mutex);
ovs_mutex_unlock(&dpdk_mutex);
- return 0;
+ return err;
}
static int