From 690d2ad4d207da5c8821b84ab467090bd515eedf Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 28 Feb 2019 11:14:22 +0100 Subject: [PATCH] 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. --- include/common/mini-clist.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/common/mini-clist.h b/include/common/mini-clist.h index aefff82fa0..d8fcb15997 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; \ -- 2.39.5