commit cee000f97c9300dbbae50118838c6d3e8d5eb9cf Author: Willy Tarreau 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 (cherry picked from commit c2aa5cb8b8ff3af27f1a962541e53f792745bc4a) Signed-off-by: Christopher Faulet 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; \