From 65bf600cc3ced517196138fb4aad6d58d4dc4220 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 23 Mar 2021 10:44:43 +0100 Subject: [PATCH] BUG/MEDIUM: release lock on idle conn killing on reached pool high count Release the lock before calling mux destroy in connect_server when trying to kill an idle connection because the pool high count has been reached. The lock must be released because the mux destroy will call srv_release_conn which also takes the lock to remove the connection from the tree. As the connection was already deleted from the tree at this stage, it is safe to release the lock, and the removal in srv_release_conn will be a noop. It does not need to be backported because it is only present in the current release. It has been introduced by 5c7086f6b06d546c5800486ed9e4bb8d8d471e09 MEDIUM: connection: protect idle conn lists with locks --- src/backend.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/backend.c b/src/backend.c index 80f00f258..3cc7adc37 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1426,9 +1426,17 @@ int connect_server(struct stream *s) conn_node = ebmb_entry(node, struct conn_hash_node, node); tokill_conn = conn_node->conn; ebmb_delete(node); + HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + + /* Release the idle lock before calling mux->destroy. + * It will in turn call srv_release_conn through + * conn_free which also uses it. + */ tokill_conn->mux->destroy(tokill_conn->ctx); } - HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + else { + HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + } /* If not, iterate over other thread's idling pool, and try to grab one */ if (!tokill_conn) {