From 5567f41d0ab61dd6843535edc8081407d599024d Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Thu, 18 Feb 2021 23:55:30 +0100 Subject: [PATCH] BUG/MEDIUM: lists: Avoid an infinite loop in MT_LIST_TRY_ADDQ(). In MT_LIST_TRY_ADDQ(), deal with the "prev" field of the element before the "next". If the element is the first in the list, then its next will already have been locked when we locked list->prev->next, so locking it again will fail, and we'll start over and over. This should be backported to 2.3. --- include/haproxy/list.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/include/haproxy/list.h b/include/haproxy/list.h index 6db2f92..40929c4 100644 --- a/include/haproxy/list.h +++ b/include/haproxy/list.h @@ -300,28 +300,28 @@ __ha_barrier_store(); \ continue; \ } \ - n2 = _HA_ATOMIC_XCHG(&el->next, MT_LIST_BUSY); \ - if (n2 != el) { /* element already linked */ \ - if (n2 != MT_LIST_BUSY) \ - el->next = n2; \ + p2 = _HA_ATOMIC_XCHG(&el->prev, MT_LIST_BUSY); \ + if (p2 != el) { \ + if (p2 != MT_LIST_BUSY) \ + el->prev = p2; \ p->next = n; \ __ha_barrier_store(); \ lh->prev = p; \ __ha_barrier_store(); \ - if (n2 == MT_LIST_BUSY) \ + if (p2 == MT_LIST_BUSY) \ continue; \ break; \ } \ - p2 = _HA_ATOMIC_XCHG(&el->prev, MT_LIST_BUSY); \ - if (p2 != el) { \ - if (p2 != MT_LIST_BUSY) \ - el->prev = p2; \ + n2 = _HA_ATOMIC_XCHG(&el->next, MT_LIST_BUSY); \ + if (n2 != el) { /* element already linked */ \ + if (n2 != MT_LIST_BUSY) \ + el->next = n2; \ p->next = n; \ - el->next = el; \ + el->prev = el; \ __ha_barrier_store(); \ lh->prev = p; \ __ha_barrier_store(); \ - if (p2 == MT_LIST_BUSY) \ + if (n2 == MT_LIST_BUSY) \ continue; \ break; \ } \ -- 1.7.10.4