]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
OPTIM/MEDIUM: proxy/server: avoid server list reordering on startup
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 22 Jul 2026 13:51:29 +0000 (15:51 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 24 Jul 2026 07:34:44 +0000 (09:34 +0200)
Prior to this patch, each server parsed from the configuration was added
at the front of the proxy list. The list was then reversed once parsing
is finished to reflect the configuration order.

Now that proxy servers list has been converted to a doubly linked list,
there is no more a reason for this. Thus, this patch changes the server
insertion order on configuration parsing : this is now performed
directly at the end of the proxy list. Reversal is unnecessary and has
been removed, so post-config performance may be slightly improved.

Peers parsing is the only module which relies on the order insertion.
Thus it has been adapted to now use the last server in its proxy.

include/haproxy/proxy.h
src/cfgparse-peers.c
src/proxy.c
src/server.c

index 0c0bc730d89104ef46adaf22af26351fa1beeff4..77589317d6bda8a7d69175e91ae63112d6c98e77 100644 (file)
@@ -352,6 +352,12 @@ static inline struct server *proxy_first_server(const struct proxy *px)
          LIST_NEXT(&px->servers, struct server *, el_px) : NULL;
 }
 
+static inline struct server *proxy_last_server(const struct proxy *px)
+{
+       return !LIST_ISEMPTY(&px->servers) ?
+         LIST_PREV(&px->servers, struct server *, el_px) : NULL;
+}
+
 static inline struct server *proxy_next_server(const struct server *srv)
 {
        if (srv->el_px.n == &srv->proxy->servers)
index 8d5b4ca2b85a3a44b1bf1f97ae925d8964cba36e..0fbf286b5f91662a017db9d6d5287de2ab4b4628 100644 (file)
@@ -365,10 +365,10 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                 * or if we are parsing a "server" line and the current peer is not the local one.
                 */
                parse_addr = (peer || !local_peer) ? SRV_PARSE_PARSE_ADDR : 0;
-               prev_srv = proxy_first_server(curpeers->peers_fe);
+               prev_srv = proxy_last_server(curpeers->peers_fe);
                err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL,
                                         SRV_PARSE_IN_PEER_SECTION|parse_addr|SRV_PARSE_INITIAL_RESOLVE);
-               if (prev_srv == proxy_first_server(curpeers->peers_fe)) {
+               if (prev_srv == proxy_last_server(curpeers->peers_fe)) {
                        /* parse_server didn't add a server:
                         * Remove the newly allocated peer.
                         */
@@ -404,7 +404,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                        goto out;
                }
 
-               srv = proxy_first_server(curpeers->peers_fe);
+               srv = proxy_last_server(curpeers->peers_fe);
 
                if (!parse_addr && bind_addr) {
                        /* local peer declared using "server": has name but no
index 8b72f9d4525a86a6222d8833836aeb2b28bcaf6c..76104a083e055306309ae32c03e6d0f5a9087580 100644 (file)
@@ -1663,7 +1663,7 @@ int proxy_finalize(struct proxy *px, int *err_code)
 {
        struct list tmp_list = LIST_HEAD_INIT(tmp_list);
        struct bind_conf *bind_conf;
-       struct server *newsrv, *newsrv_back;
+       struct server *newsrv;
        struct switching_rule *rule;
        struct server_rule *srule;
        struct sticking_rule *mrule;
@@ -2495,13 +2495,6 @@ int proxy_finalize(struct proxy *px, int *err_code)
                        break;
        }
 
-       /* first, we will invert the servers list order */
-       list_for_each_entry_safe(newsrv, newsrv_back, &px->servers, el_px) {
-               LIST_DEL_INIT(&newsrv->el_px);
-               LIST_INSERT(&tmp_list, &newsrv->el_px);
-       }
-       LIST_SPLICE(&px->servers, &tmp_list);
-
        /* Check that no server name conflicts. This causes trouble in the stats.
         * We only emit an error for the first conflict affecting each server,
         * in order to avoid combinatory explosion if all servers have the same
index 0e66762fc0270cd7ce16ded8b50f26f98f8fcc16..f4d3eb04ee1eb38b8a85c076716ce10d48bff161 100644 (file)
@@ -3154,6 +3154,7 @@ struct server *new_server(struct proxy *proxy)
 
        srv->obj_type = OBJ_TYPE_SERVER;
        srv->proxy = proxy;
+       LIST_APPEND(&proxy->servers, &srv->el_px);
        MT_LIST_APPEND(&all_servers, &srv->global_list);
        LIST_INIT(&srv->srv_rec_item);
        LIST_INIT(&srv->ip_rec_item);
@@ -3184,18 +3185,6 @@ struct server *new_server(struct proxy *proxy)
        HA_RWLOCK_INIT(&srv->ssl_ctx.lock);
 #endif
 
-       // add server to proxy list:
-       if (!(proxy->flags & PR_FL_CHECKED)) {
-               /* they are linked backwards first during parsing
-                * This will be restablished after parsing.
-                */
-               LIST_INSERT(&proxy->servers, &srv->el_px);
-       }
-       else {
-               // runtime, add the server at the end of the list
-               LIST_APPEND(&proxy->servers, &srv->el_px);
-       }
-
        HA_RWLOCK_INIT(&srv->path_params.param_lock);
 
        return srv;