diff mbox

[ovs-dev,0/2] Per numa node barriers for pmd threads

Message ID 1450794408-17970-1-git-send-email-i.maximets@samsung.com
State Not Applicable
Headers show

Commit Message

Ilya Maximets Dec. 22, 2015, 2:26 p.m. UTC
While reloading, two PMD threads, one already reloaded and
one not yet reloaded, can poll same queue of the same port.

This may be easily reproduced using that patch:

---

How To:
<-- ovs-vsctl add-port ovs_br0 dpdk0 -- set Interface dpdk0 type=dpdk -->
<-- ovs-vsctl add-port ovs_br0 dpdk1 -- set Interface dpdk1 type=dpdk -->
49:58Z|00054|dpif_netdev(pmd99) |INFO|Core 0 processing port 'dpdk0'
49:58Z|00054|dpif_netdev(pmd100)|INFO|Core 1 processing port 'dpdk1'
49:58Z|00075|dpif_netdev|INFO|Created 2 pmd threads on numa node 0
<-- ovs-vsctl del-port ovs_br0 dpdk0 -->
50:20Z|00083|dpif_netdev(pmd99)|INFO|Core 0 processing port 'dpdk1'
ovs-vswitchd(pmd100): lib/dpif-netdev.c:2571:
assertion ovs_refcount_unref_relaxed(&rxq->ref_cnt) == 2 failed in dp_netdev_process_rxq_port()

Program received signal SIGABRT, Aborted.

Fix that by introducing per numa node barriers prior to polling.

Ilya Maximets (2):
  poll: Suppress logging for pmd threads.
  dpif-netdev: Per numa node barriers for pmd threads.

 lib/dpif-netdev.c | 53 ++++++++++++++++++++++++++++++++++++++++-------------
 lib/ovs-thread.c  |  9 +++++++++
 lib/ovs-thread.h  |  1 +
 lib/poll-loop.c   |  4 +++-
 lib/timeval.c     |  2 +-
 5 files changed, 54 insertions(+), 15 deletions(-)
diff mbox

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index ad4a665..8b744d9 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -48,6 +48,7 @@ 
 #include "match.h"
 #include "netdev.h"
 #include "netdev-dpdk.h"
+#include "netdev-provider.h"
 #include "netdev-vport.h"
 #include "netlink.h"
 #include "odp-execute.h"
@@ -2524,7 +2524,9 @@  dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread *pmd,
     int error, cnt;
 
     cycles_count_start(pmd);
+    ovs_refcount_ref(&rxq->ref_cnt);
     error = netdev_rxq_recv(rxq, packets, &cnt);
+    ovs_assert(ovs_refcount_unref_relaxed(&rxq->ref_cnt) == 2);
     cycles_count_end(pmd, PMD_CYCLES_POLLING);
     if (!error) {
         int i;
diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h
index a33bb3b..d377066 100644
--- a/lib/netdev-provider.h
+++ b/lib/netdev-provider.h
@@ -22,6 +22,7 @@ 
 #include "connectivity.h"
 #include "netdev.h"
 #include "list.h"
+#include "ovs-atomic.h"
 #include "ovs-numa.h"
 #include "packets.h"
 #include "seq.h"
@@ -88,6 +89,7 @@  struct netdev **netdev_get_vports(size_t *size);
 struct netdev_rxq {
     struct netdev *netdev;      /* Owns a reference to the netdev. */
     int queue_id;
+    struct ovs_refcount ref_cnt;
 };
 
 struct netdev *netdev_rxq_get_netdev(const struct netdev_rxq *);
diff --git a/lib/netdev.c b/lib/netdev.c
index e3b70b1..b01c04c 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -601,6 +601,7 @@  netdev_rxq_open(struct netdev *netdev, struct netdev_rxq **rxp, int id)
         if (rx) {
             rx->netdev = netdev;
             rx->queue_id = id;
+            ovs_refcount_init(&rx->ref_cnt);
             error = netdev->netdev_class->rxq_construct(rx);
             if (!error) {
                 netdev_ref(netdev);