From: Amaury Denoyelle Date: Wed, 22 Jul 2026 13:51:29 +0000 (+0200) Subject: OPTIM/MEDIUM: proxy/server: avoid server list reordering on startup X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=029add93aeec169c7c0648e04b8d2f6c13a151b6;p=thirdparty%2Fhaproxy.git OPTIM/MEDIUM: proxy/server: avoid server list reordering on startup 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. --- diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index 0c0bc730d..77589317d 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -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) diff --git a/src/cfgparse-peers.c b/src/cfgparse-peers.c index 8d5b4ca2b..0fbf286b5 100644 --- a/src/cfgparse-peers.c +++ b/src/cfgparse-peers.c @@ -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 diff --git a/src/proxy.c b/src/proxy.c index 8b72f9d45..76104a083 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -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 diff --git a/src/server.c b/src/server.c index 0e66762fc..f4d3eb04e 100644 --- a/src/server.c +++ b/src/server.c @@ -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;