diff --git a/include/proto/connection.h b/include/proto/connection.h index 1dc0512f4..45b8a8a53 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -694,6 +694,7 @@ static inline void conn_free(struct connection *conn) if (conn->idle_time > 0) { struct server *srv = __objt_server(conn->target); HA_ATOMIC_SUB(&srv->curr_idle_conns, 1); + srv->curr_idle_thr[tid]--; } conn_force_unsubscribe(conn); diff --git a/include/proto/server.h b/include/proto/server.h index 51d1015e9..9467f697a 100644 --- a/include/proto/server.h +++ b/include/proto/server.h @@ -253,6 +253,7 @@ static inline int srv_add_to_idle_list(struct server *srv, struct connection *co } LIST_DEL(&conn->list); LIST_ADDQ(&srv->idle_orphan_conns[tid], &conn->list); + srv->curr_idle_thr[tid]++; conn->idle_time = now_ms; if (!(task_in_wq(srv->idle_task[tid])) && diff --git a/include/types/server.h b/include/types/server.h index e4371af00..eae7d450d 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -225,6 +225,7 @@ struct server { unsigned int pool_purge_delay; /* Delay before starting to purge the idle conns pool */ unsigned int max_idle_conns; /* Max number of connection allowed in the orphan connections list */ unsigned int curr_idle_conns; /* Current number of orphan idling connections */ + unsigned int *curr_idle_thr; /* Current number of orphan idling connections per thread */ int max_reuse; /* Max number of requests on a same connection */ struct task **idle_task; /* task responsible for cleaning idle orphan connections */ struct task *warmup; /* the task dedicated to the warmup when slowstart is set */ diff --git a/src/backend.c b/src/backend.c index 3c752a273..d15020aa6 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1344,6 +1344,7 @@ int connect_server(struct stream *s) LIST_DEL(&srv_conn->list); srv_conn->idle_time = 0; HA_ATOMIC_SUB(&srv->curr_idle_conns, 1); + srv->curr_idle_thr[tid]--; LIST_ADDQ(&srv->idle_conns[tid], &srv_conn->list); if (LIST_ISEMPTY(&srv->idle_orphan_conns[tid])) task_unlink_wq(srv->idle_task[tid]); diff --git a/src/cfgparse.c b/src/cfgparse.c index 59ba77376..fde3097e8 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3593,6 +3593,9 @@ out_uri_auth_compat: newsrv->idle_task[i]->process = srv_cleanup_idle_connections; newsrv->idle_task[i]->context = newsrv; } + newsrv->curr_idle_thr = calloc(global.nbthread, sizeof(int)); + if (!newsrv->curr_idle_thr) + goto err; continue; err: ha_alert("parsing [%s:%d] : failed to allocate idle connection tasks for server '%s'.\n", diff --git a/src/haproxy.c b/src/haproxy.c index 7c434b361..50133fb1e 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -2436,6 +2436,7 @@ void deinit(void) free(s->priv_conns); free(s->safe_conns); free(s->idle_orphan_conns); + free(s->curr_idle_thr); if (s->idle_task) { int i; diff --git a/src/server.c b/src/server.c index 312aa1994..4068255e5 100644 --- a/src/server.c +++ b/src/server.c @@ -5309,7 +5309,7 @@ struct task *srv_cleanup_idle_connections(struct task *task, void *context, unsi { struct server *srv = context; struct connection *conn, *conn_back; - unsigned int to_destroy = srv->curr_idle_conns / 2 + (srv->curr_idle_conns & 1); + unsigned int to_destroy = srv->curr_idle_thr[tid] / 2 + (srv->curr_idle_thr[tid] & 1); unsigned int i = 0;