commit cee000f97c9300dbbae50118838c6d3e8d5eb9cf
|
|
Author: Willy Tarreau <w@1wt.eu>
|
|
Date: Thu Feb 28 11:14:22 2019 +0100
|
|
|
|
BUG/MEDIUM: list: add missing store barriers when updating elements and head
|
|
|
|
Commit a8434ec14 ("MINOR: lists: Implement locked variations.")
|
|
introduced locked lists which use the elements pointers as locks
|
|
for concurrent operations. Under heavy stress the lists occasionally
|
|
fail. The cause is a missing barrier at some points when updating
|
|
the list element and the head : nothing prevents the compiler (or
|
|
CPU) from updating the list head first before updating the element,
|
|
making another thread jump to a wrong location. This patch simply
|
|
adds the missing barriers before these two opeations.
|
|
|
|
This will have to be backported if the commit above is backported.
|
|
|
|
(cherry picked from commit 690d2ad4d207da5c8821b84ab467090bd515eedf)
|
|
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
|
(cherry picked from commit c2aa5cb8b8ff3af27f1a962541e53f792745bc4a)
|
|
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
|
|
|
diff --git a/include/common/mini-clist.h b/include/common/mini-clist.h
|
|
index 51c61051..92a995c9 100644
|
|
--- a/include/common/mini-clist.h
|
|
+++ b/include/common/mini-clist.h
|
|
@@ -189,6 +189,7 @@ struct cond_wordlist {
|
|
} \
|
|
(el)->n = n; \
|
|
(el)->p = p; \
|
|
+ __ha_barrier_store(); \
|
|
n->p = (el); \
|
|
__ha_barrier_store(); \
|
|
p->n = (el); \
|
|
@@ -214,6 +215,7 @@ struct cond_wordlist {
|
|
} \
|
|
(el)->n = n; \
|
|
(el)->p = p; \
|
|
+ __ha_barrier_store(); \
|
|
n->p = (el); \
|
|
__ha_barrier_store(); \
|
|
p->n = (el); \
|
|
@@ -276,6 +278,7 @@ struct cond_wordlist {
|
|
continue; \
|
|
if (n == (lh)) { \
|
|
(lh)->n = lh; \
|
|
+ __ha_barrier_store(); \
|
|
_ret = NULL; \
|
|
break; \
|
|
} \
|
|
@@ -288,6 +291,7 @@ struct cond_wordlist {
|
|
n2 = HA_ATOMIC_XCHG(&n->n, LLIST_BUSY); \
|
|
if (n2 == LLIST_BUSY) { \
|
|
n->p = p; \
|
|
+ __ha_barrier_store(); \
|
|
(lh)->n = n; \
|
|
__ha_barrier_store(); \
|
|
continue; \
|
|
@@ -296,6 +300,7 @@ struct cond_wordlist {
|
|
if (p2 == LLIST_BUSY) { \
|
|
n->n = n2; \
|
|
n->p = p; \
|
|
+ __ha_barrier_store(); \
|
|
(lh)->n = n; \
|
|
__ha_barrier_store(); \
|
|
continue; \
|