[dpdk-dev] [PATCH v2] ring: check for zero objects mc dequeue / mp enqueue
Lazaros Koromilas
l at nofutznetworks.com
Thu Mar 17 16:49:43 CET 2016
Issuing a zero objects dequeue with a single consumer has no effect.
Doing so with multiple consumers, can get more than one thread to succeed
the compare-and-set operation and observe starvation or even deadlock in
the while loop that checks for preceding dequeues. The problematic piece
of code when n = 0:
cons_next = cons_head + n;
success = rte_atomic32_cmpset(&r->cons.head, cons_head, cons_next);
The same is possible on the enqueue path.
Signed-off-by: Lazaros Koromilas <l at nofutznetworks.com>
---
lib/librte_ring/rte_ring.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
index 943c97c..eb45e41 100644
--- a/lib/librte_ring/rte_ring.h
+++ b/lib/librte_ring/rte_ring.h
@@ -431,6 +431,11 @@ __rte_ring_mp_do_enqueue(struct rte_ring *r, void * const *obj_table,
uint32_t mask = r->prod.mask;
int ret;
+ /* Avoid the unnecessary cmpset operation below, which is also
+ * potentially harmful when n equals 0. */
+ if (n == 0)
+ return 0;
+
/* move prod.head atomically */
do {
/* Reset n to the initial burst count */
@@ -618,6 +623,11 @@ __rte_ring_mc_do_dequeue(struct rte_ring *r, void **obj_table,
unsigned i, rep = 0;
uint32_t mask = r->prod.mask;
+ /* Avoid the unnecessary cmpset operation below, which is also
+ * potentially harmful when n equals 0. */
+ if (n == 0)
+ return 0;
+
/* move cons.head atomically */
do {
/* Restore n as it may change every loop */
--
1.9.1
More information about the dev
mailing list