]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: queue/threads: make pendconn_redistribute not lock the server
authorWilly Tarreau <w@1wt.eu>
Tue, 21 Aug 2018 16:11:03 +0000 (18:11 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 21 Aug 2018 16:11:03 +0000 (18:11 +0200)
Since commit 3ff577e ("MAJOR: server: make server state changes
synchronous again"), srv_update_status() is called with the server
lock held. It calls (among others) pendconn_redistribute() which used
to take this lock, causing CPU loops by default, or crashes if build
with -DDEBUG_THREAD. Since this function is not called from any other
place anymore, it doesn't require the lock on its own so let's simply
drop it from there.

No backport is needed, this is 1.9-specific.

src/queue.c

index 3e9371bfaaff24c6fa5e32725583b29105aad87d..245fb7dad5adcedfd130645ca1c52a5e7275689b 100644 (file)
@@ -395,7 +395,8 @@ struct pendconn *pendconn_add(struct stream *strm)
 }
 
 /* Redistribute pending connections when a server goes down. The number of
- * connections redistributed is returned.
+ * connections redistributed is returned. It must be called with the server
+ * lock held.
  */
 int pendconn_redistribute(struct server *s)
 {
@@ -408,7 +409,6 @@ int pendconn_redistribute(struct server *s)
        if ((s->proxy->options & (PR_O_REDISP|PR_O_PERSIST)) != PR_O_REDISP)
                return 0;
 
-       HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
        for (node = eb32_first(&s->pendconns); node; node = eb32_next(node)) {
                p = eb32_entry(&node, struct pendconn, node);
                if (p->strm_flags & SF_FORCE_PRST)
@@ -420,7 +420,6 @@ int pendconn_redistribute(struct server *s)
 
                task_wakeup(p->strm->task, TASK_WOKEN_RES);
        }
-       HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
        return xferred;
 }