diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h index 094e54cde..08f4313fe 100644 --- a/include/haproxy/connection.h +++ b/include/haproxy/connection.h @@ -393,8 +393,11 @@ static inline struct connection *conn_new(void *target) struct connection *conn; conn = pool_alloc(pool_head_connection); - if (likely(conn != NULL)) + if (likely(conn != NULL)) { conn_init(conn, target); + if (obj_type(target) == OBJ_TYPE_SERVER) + srv_use_idle_conn(__objt_server(target), conn); + } return conn; } diff --git a/include/haproxy/server.h b/include/haproxy/server.h index 3ad60d0cd..929eeba6f 100644 --- a/include/haproxy/server.h +++ b/include/haproxy/server.h @@ -239,6 +239,30 @@ static inline enum srv_initaddr srv_get_next_initaddr(unsigned int *list) return ret; } +static inline void srv_use_idle_conn(struct server *srv, struct connection *conn) +{ + if (conn->flags & CO_FL_LIST_MASK) { + conn->idle_time = 0; + _HA_ATOMIC_SUB(&srv->curr_idle_conns, 1); + _HA_ATOMIC_SUB(conn->flags & CO_FL_SAFE_LIST ? &srv->curr_safe_nb : &srv->curr_idle_nb, 1); + _HA_ATOMIC_SUB(&srv->curr_idle_thr[tid], 1); + conn->flags &= ~CO_FL_LIST_MASK; + __ha_barrier_atomic_store(); + LIST_ADDQ(&srv->available_conns[tid], mt_list_to_list(&conn->list)); + } + + _HA_ATOMIC_ADD(&srv->curr_used_conns, 1); + + /* It's ok not to do that atomically, we don't need an + * exact max. + */ + if (srv->max_used_conns < srv->curr_used_conns) + srv->max_used_conns = srv->curr_used_conns; + + if (srv->est_need_conns < srv->curr_used_conns) + srv->est_need_conns = srv->curr_used_conns; +} + /* This adds an idle connection to the server's list if the connection is * reusable, not held by any owner anymore, but still has available streams. */ diff --git a/src/backend.c b/src/backend.c index 47f4bffb5..372389aae 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1166,13 +1166,8 @@ static struct connection *conn_backend_get(struct server *srv, int is_safe) conn = NULL; done: if (conn) { - conn->idle_time = 0; _HA_ATOMIC_STORE(&srv->next_takeover, (i + 1 == global.nbthread) ? 0 : i + 1); - _HA_ATOMIC_SUB(&srv->curr_idle_conns, 1); - _HA_ATOMIC_SUB(&srv->curr_idle_thr[i], 1); - _HA_ATOMIC_SUB(is_safe ? &srv->curr_safe_nb : &srv->curr_idle_nb, 1); - __ha_barrier_atomic_store(); - LIST_ADDQ(&srv->available_conns[tid], mt_list_to_list(&conn->list)); + srv_use_idle_conn(srv, conn); } return conn; } @@ -1201,7 +1196,6 @@ int connect_server(struct stream *s) int reuse = 0; int init_mux = 0; int err; - int was_unused = 0; /* This will catch some corner cases such as lying connections resulting from @@ -1251,20 +1245,17 @@ int connect_server(struct stream *s) * try idle then safe. */ srv_conn = conn_backend_get(srv, 0); - was_unused = 1; } else if (srv->safe_conns && ((s->txn && (s->txn->flags & TX_NOT_FIRST)) || (s->be->options & PR_O_REUSE_MASK) >= PR_O_REUSE_AGGR) && srv->curr_safe_nb > 0) { srv_conn = conn_backend_get(srv, 1); - was_unused = 1; } else if (srv->idle_conns && ((s->be->options & PR_O_REUSE_MASK) == PR_O_REUSE_ALWS) && srv->curr_idle_nb > 0) { srv_conn = conn_backend_get(srv, 0); - was_unused = 1; } /* If we've picked a connection from the pool, we now have to * detach it. We may have to get rid of the previous idle @@ -1272,10 +1263,8 @@ int connect_server(struct stream *s) * other owner's. That way it may remain alive for others to * pick. */ - if (srv_conn) { + if (srv_conn) reuse = 1; - srv_conn->flags &= ~CO_FL_LIST_MASK; - } } } @@ -1369,7 +1358,6 @@ int connect_server(struct stream *s) /* no reuse or failed to reuse the connection above, pick a new one */ if (!srv_conn) { srv_conn = conn_new(s->target); - was_unused = 1; srv_cs = NULL; srv_conn->owner = s->sess; @@ -1377,17 +1365,6 @@ int connect_server(struct stream *s) conn_set_private(srv_conn); } - if (srv_conn && srv && was_unused) { - _HA_ATOMIC_ADD(&srv->curr_used_conns, 1); - /* It's ok not to do that atomically, we don't need an - * exact max. - */ - if (srv->max_used_conns < srv->curr_used_conns) - srv->max_used_conns = srv->curr_used_conns; - - if (srv->est_need_conns < srv->curr_used_conns) - srv->est_need_conns = srv->curr_used_conns; - } if (!srv_conn || !sockaddr_alloc(&srv_conn->dst)) { if (srv_conn) conn_free(srv_conn); diff --git a/src/tcpcheck.c b/src/tcpcheck.c index 6f962cc6b..e83b915b9 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -1026,9 +1026,6 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec /* Maybe there were an older connection we were waiting on */ check->wait_list.events = 0; - if (s) { - _HA_ATOMIC_ADD(&s->curr_used_conns, 1); - } /* no client address */ if (!sockaddr_alloc(&conn->dst)) {