]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: threads/queue: avoid recursive locking in pendconn_get_next_strm()
authorWilly Tarreau <w@1wt.eu>
Sun, 26 Nov 2017 17:48:14 +0000 (18:48 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 26 Nov 2017 17:50:30 +0000 (18:50 +0100)
pendconn_get_next_strm() is called from process_srv_queue() under the
server lock, and calls stream_add_srv_conn() with this lock held, while
the latter tries to take it again. This results in a deadlock when
a server's maxconn is reached and haproxy is built with thread support.

include/proto/stream.h
src/queue.c

index 938c58de549b517d5c719681b1d2e3986113ee8f..f3fb095ff0314c9ce8029391169160948378ec2a 100644 (file)
@@ -296,11 +296,16 @@ static void inline stream_inc_http_err_ctr(struct stream *s)
        }
 }
 
-static void inline stream_add_srv_conn(struct stream *sess, struct server *srv)
+static void inline __stream_add_srv_conn(struct stream *sess, struct server *srv)
 {
-       HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
        sess->srv_conn = srv;
        LIST_ADD(&srv->actconns, &sess->by_srv);
+}
+
+static void inline stream_add_srv_conn(struct stream *sess, struct server *srv)
+{
+       HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
+       __stream_add_srv_conn(sess, srv);
        HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
 }
 
index 1796ac147f8406d95a0bad92866a4c964f1d60c2..1dea7d53baf6fb49f8835247e65e8d8a1766827d 100644 (file)
@@ -124,7 +124,7 @@ static struct stream *pendconn_get_next_strm(struct server *srv, struct proxy *p
        /* we want to note that the stream has now been assigned a server */
        strm->flags |= SF_ASSIGNED;
        strm->target = &srv->obj_type;
-       stream_add_srv_conn(strm, srv);
+       __stream_add_srv_conn(strm, srv);
        HA_ATOMIC_ADD(&srv->served, 1);
        HA_ATOMIC_ADD(&srv->proxy->served, 1);
        if (px->lbprm.server_take_conn)