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

  1. commit cee000f97c9300dbbae50118838c6d3e8d5eb9cf
  2. Author: Willy Tarreau <w@1wt.eu>
  3. Date: Thu Feb 28 11:14:22 2019 +0100
  4. BUG/MEDIUM: list: add missing store barriers when updating elements and head
  5. Commit a8434ec14 ("MINOR: lists: Implement locked variations.")
  6. introduced locked lists which use the elements pointers as locks
  7. for concurrent operations. Under heavy stress the lists occasionally
  8. fail. The cause is a missing barrier at some points when updating
  9. the list element and the head : nothing prevents the compiler (or
  10. CPU) from updating the list head first before updating the element,
  11. making another thread jump to a wrong location. This patch simply
  12. adds the missing barriers before these two opeations.
  13. This will have to be backported if the commit above is backported.
  14. (cherry picked from commit 690d2ad4d207da5c8821b84ab467090bd515eedf)
  15. Signed-off-by: Willy Tarreau <w@1wt.eu>
  16. (cherry picked from commit c2aa5cb8b8ff3af27f1a962541e53f792745bc4a)
  17. Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
  18. diff --git a/include/common/mini-clist.h b/include/common/mini-clist.h
  19. index 51c61051..92a995c9 100644
  20. --- a/include/common/mini-clist.h
  21. +++ b/include/common/mini-clist.h
  22. @@ -189,6 +189,7 @@ struct cond_wordlist {
  23. } \
  24. (el)->n = n; \
  25. (el)->p = p; \
  26. + __ha_barrier_store(); \
  27. n->p = (el); \
  28. __ha_barrier_store(); \
  29. p->n = (el); \
  30. @@ -214,6 +215,7 @@ struct cond_wordlist {
  31. } \
  32. (el)->n = n; \
  33. (el)->p = p; \
  34. + __ha_barrier_store(); \
  35. n->p = (el); \
  36. __ha_barrier_store(); \
  37. p->n = (el); \
  38. @@ -276,6 +278,7 @@ struct cond_wordlist {
  39. continue; \
  40. if (n == (lh)) { \
  41. (lh)->n = lh; \
  42. + __ha_barrier_store(); \
  43. _ret = NULL; \
  44. break; \
  45. } \
  46. @@ -288,6 +291,7 @@ struct cond_wordlist {
  47. n2 = HA_ATOMIC_XCHG(&n->n, LLIST_BUSY); \
  48. if (n2 == LLIST_BUSY) { \
  49. n->p = p; \
  50. + __ha_barrier_store(); \
  51. (lh)->n = n; \
  52. __ha_barrier_store(); \
  53. continue; \
  54. @@ -296,6 +300,7 @@ struct cond_wordlist {
  55. if (p2 == LLIST_BUSY) { \
  56. n->n = n2; \
  57. n->p = p; \
  58. + __ha_barrier_store(); \
  59. (lh)->n = n; \
  60. __ha_barrier_store(); \
  61. continue; \