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 dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev