DPDK rings don't need one TX queue per PMD thread and don't support multiple
queues (set_multiq function is undefined). To fix operation with DPDK rings,
this patch ignores EOPNOTSUPP error on netdev_set_multiq() and ignores, for
DPDK ring netdevs, the provided queue id (= PMD thread core id) in
netdev_dpdk_send().

Signed-off-by: David Verbeiren <david.verbei...@intel.com>
---
 lib/dpif-netdev.c |  4 ++--
 lib/netdev-dpdk.c | 11 +++++++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 6b8201b..f81d638 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -786,7 +786,7 @@ do_add_port(struct dp_netdev *dp, const char *devname, 
const char *type,
         /* There can only be ovs_numa_get_n_cores() pmd threads,
          * so creates a txq for each. */
         error = netdev_set_multiq(netdev, n_cores, dp->n_dpdk_rxqs);
-        if (error) {
+        if (error && (error != EOPNOTSUPP)) {
             VLOG_ERR("%s, cannot set multiq", devname);
             return errno;
         }
@@ -1950,7 +1950,7 @@ dpif_netdev_pmd_set(struct dpif *dpif, unsigned int 
n_rxqs, const char *cmask)
                 /* Sets the new rx queue config.  */
                 err = netdev_set_multiq(port->netdev, ovs_numa_get_n_cores(),
                                         n_rxqs);
-                if (err) {
+                if (err && (err != EOPNOTSUPP)) {
                     VLOG_ERR("Failed to set dpdk interface %s rx_queue to:"
                              " %u", netdev_get_name(port->netdev),
                              n_rxqs);
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 9c93768..c72fe31 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -212,6 +212,7 @@ struct netdev_rxq_dpdk {
 static bool thread_is_pmd(void);
 
 static int netdev_dpdk_construct(struct netdev *);
+static int netdev_dpdk_ring_construct(struct netdev *);
 
 static bool
 is_dpdk_class(const struct netdev_class *class)
@@ -219,6 +220,12 @@ is_dpdk_class(const struct netdev_class *class)
     return class->construct == netdev_dpdk_construct;
 }
 
+static bool
+is_dpdk_ring_class(const struct netdev_class *class)
+{
+    return class->construct == netdev_dpdk_ring_construct;
+}
+
 /* XXX: use dpdk malloc for entire OVS. infact huge page shld be used
  * for all other sengments data, bss and text. */
 
@@ -853,6 +860,10 @@ netdev_dpdk_send(struct netdev *netdev, int qid, struct 
dpif_packet **pkts,
     int ret;
     int i;
 
+    if (is_dpdk_ring_class(netdev->netdev_class)) {
+        qid = 0;    /* DPDK Rings have a single TX queue */
+    }
+
     if (!may_steal || pkts[0]->ofpbuf.source != OFPBUF_DPDK) {
         dpdk_do_tx_copy(netdev, qid, pkts, cnt);
 
-- 
1.8.3.2

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to