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:
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);
---
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(-)
--
2.1.4
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev