]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: server: shard by thread sess_conns member
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 14 Aug 2025 16:18:01 +0000 (18:18 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 28 Aug 2025 12:52:29 +0000 (14:52 +0200)
Server member <sess_conns> is a mt_list which contains every backend
connections attached to a session which targets this server. These
connecions are not present in idle server trees.

The main utility of this list is to be able to cleanup these connections
prior to removing a server via "del server" CLI. However, this procedure
will be adjusted by a future patch. As such, <sess_conns> member must be
moved into srv_per_thread struct. Effectively, this duplicates a list
for every threads.

This commit does not introduce functional change. Its goal is to ensure
that these connections are now ordered by their owning thread, which
will allow to implement a purge, similarly to idle connections attached
to servers.

include/haproxy/server-t.h
src/server.c
src/session.c

index 780803384b31f4aa1e1d77583b987c436ce17633..85dcd63da2dbef44b15a929a2a8523dd9ebe5c9f 100644 (file)
@@ -266,6 +266,7 @@ struct srv_per_thread {
        struct eb_root idle_conns;              /* Shareable idle connections */
        struct eb_root safe_conns;              /* Safe idle connections */
        struct eb_root avail_conns;             /* Connections in use, but with still new streams available */
+       struct mt_list sess_conns;              /* Connections attached to a session which cannot be shared across clients */
 
        /* Secondary idle conn storage used in parallel to idle/safe trees.
         * Used to sort them by last usage and purge them in reverse order.
@@ -388,8 +389,6 @@ struct server {
        unsigned int max_used_conns;            /* Max number of used connections (the counter is reset at each connection purges */
        unsigned int est_need_conns;            /* Estimate on the number of needed connections (max of curr and previous max_used) */
 
-       struct mt_list sess_conns;              /* list of private conns managed by a session on this server */
-
        /* Element below are usd by LB algorithms and must be doable in
         * parallel to other threads reusing connections above.
         */
index d75d8f39ec2f4698031d2f3e69fbc6aabfc1a20b..b469b7ca85e62b5d2d079e1f651b54addc1ea60b 100644 (file)
@@ -3072,8 +3072,6 @@ struct server *new_server(struct proxy *proxy)
        srv->agent.proxy = proxy;
        srv->xprt  = srv->check.xprt = srv->agent.xprt = xprt_get(XPRT_RAW);
 
-       MT_LIST_INIT(&srv->sess_conns);
-
        guid_init(&srv->guid);
        MT_LIST_INIT(&srv->watcher_list);
 
@@ -5935,6 +5933,7 @@ static int srv_init_per_thr(struct server *srv)
                srv->per_thr[i].idle_conns = EB_ROOT;
                srv->per_thr[i].safe_conns = EB_ROOT;
                srv->per_thr[i].avail_conns = EB_ROOT;
+               MT_LIST_INIT(&srv->per_thr[i].sess_conns);
                MT_LIST_INIT(&srv->per_thr[i].streams);
 
                LIST_INIT(&srv->per_thr[i].idle_conn_list);
@@ -6428,29 +6427,34 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap
        BUG_ON(srv->curr_idle_conns);
 
        /* Close idle private connections attached to this server. */
-       MT_LIST_FOR_EACH_ENTRY_LOCKED(sess_conns, &srv->sess_conns, srv_el, back) {
-               struct connection *conn, *conn_back;
-               list_for_each_entry_safe(conn, conn_back, &sess_conns->conn_list, sess_el) {
-
-                       /* Only idle connections should be present if srv_check_for_deletion() is true. */
-                       BUG_ON(!(conn->flags & CO_FL_SESS_IDLE));
-                       --((struct session *)conn->owner)->idle_conns;
-
-                       LIST_DEL_INIT(&conn->sess_el);
-                       conn->owner = NULL;
-
-                       if (sess_conns->tid != tid) {
-                               if (conn->mux && conn->mux->takeover)
-                                       conn->mux->takeover(conn, sess_conns->tid, 1);
-                               else if (conn->xprt && conn->xprt->takeover)
-                                       conn->xprt->takeover(conn, conn->ctx, sess_conns->tid, 1);
+       for (i = tid;;) {
+               MT_LIST_FOR_EACH_ENTRY_LOCKED(sess_conns, &srv->per_thr[i].sess_conns, srv_el, back) {
+                       struct connection *conn, *conn_back;
+                       list_for_each_entry_safe(conn, conn_back, &sess_conns->conn_list, sess_el) {
+
+                               /* Only idle connections should be present if srv_check_for_deletion() is true. */
+                               BUG_ON(!(conn->flags & CO_FL_SESS_IDLE));
+                               --((struct session *)conn->owner)->idle_conns;
+
+                               LIST_DEL_INIT(&conn->sess_el);
+                               conn->owner = NULL;
+
+                               if (sess_conns->tid != tid) {
+                                       if (conn->mux && conn->mux->takeover)
+                                               conn->mux->takeover(conn, sess_conns->tid, 1);
+                                       else if (conn->xprt && conn->xprt->takeover)
+                                               conn->xprt->takeover(conn, conn->ctx, sess_conns->tid, 1);
+                               }
+                               conn_release(conn);
                        }
-                       conn_release(conn);
+
+                       LIST_DELETE(&sess_conns->sess_el);
+                       pool_free(pool_head_sess_priv_conns, sess_conns);
+                       sess_conns = NULL;
                }
 
-               LIST_DELETE(&sess_conns->sess_el);
-               pool_free(pool_head_sess_priv_conns, sess_conns);
-               sess_conns = NULL;
+               if ((i = ((i + 1 == global.nbthread) ? 0 : i + 1)) == tid)
+                       break;
        }
 
        /* removing cannot fail anymore when we reach this:
index 5e99c92f19a5b98ac67ec32e6ac211064b3ed8ae..8f871f815c8f99139aa36a6ae5025d7a48f81abb 100644 (file)
@@ -617,7 +617,7 @@ static struct sess_priv_conns *sess_alloc_sess_conns(struct session *sess,
        MT_LIST_INIT(&pconns->srv_el);
        /* If <target> endpoint is a server, also attach storage element into it. */
        if ((srv = objt_server(target)))
-               MT_LIST_APPEND(&srv->sess_conns, &pconns->srv_el);
+               MT_LIST_APPEND(&srv->per_thr[tid].sess_conns, &pconns->srv_el);
 
        pconns->tid = tid;