You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

66 lines
3.3 KiB

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; \