]> git.kaiwu.me - haproxy.git/commitdiff
MEDIUM: servers: Remove cur_sess, and use served instead
authorOlivier Houchard <ohouchard@haproxy.com>
Tue, 3 Feb 2026 06:14:25 +0000 (07:14 +0100)
committerOlivier Houchard <cognet@ci0.org>
Mon, 2 Mar 2026 12:46:17 +0000 (13:46 +0100)
In struct server, cur_sess and served mostly have the same purpose.
We can just remove cur_sess, and use served instead, both share the same
cache line, and that cache line is quite busy, so removing some atomic
operation on it can be beneficial.

14 files changed:
dev/gdb/servers.gdb
include/haproxy/queue.h
include/haproxy/server-t.h
src/backend.c
src/check.c
src/cli.c
src/extcheck.c
src/haproxy.c
src/hlua_fcn.c
src/http_ana.c
src/log.c
src/server.c
src/stats-proxy.c
src/stream.c

index 8aad06bd504c12c49f4346b3e478cc443f9670bc..981339b5e2eb2e02fe0b2b768e8f8b4af508f194 100644 (file)
@@ -3,7 +3,7 @@ define px_list_srv
   set $h = (struct proxy *)$arg0
   set $p = ($h)->srv
   while ($p != 0)
-    printf "%#lx %s maxconn=%u cur_sess=%u max_sess=%u served=%u queued=%u st=%u->%u ew=%u sps_max=%u\n", $p, $p->id, $p->maxconn, $p->cur_sess, $p->counters.cur_sess_max, $p->served, $p->queue.length, $p->cur_state, $p->next_state, $p->cur_eweight, $p->counters.sps_max
+    printf "%#lx %s maxconn=%u max_sess=%u served=%u queued=%u st=%u->%u ew=%u sps_max=%u\n", $p, $p->id, $p->maxconn, $p->counters.cur_sess_max, $p->served, $p->queue.length, $p->cur_state, $p->next_state, $p->cur_eweight, $p->counters.sps_max
     set $p = ($p)->next
   end
 end
index 524750d8694b6ed5d0c123d2ed010fe702e9aba6..41fc8b7372727c1dd0169ee8b508ba7432f07303 100644 (file)
@@ -78,7 +78,7 @@ static inline void pendconn_free(struct stream *s)
 
 /* Returns 0 if all slots are full on a server, or 1 if there are slots available. */
 static inline int server_has_room(const struct server *s) {
-       return !s->maxconn || s->cur_sess < srv_dynamic_maxconn(s);
+       return !s->maxconn || s->served < srv_dynamic_maxconn(s);
 }
 
 /* returns 0 if nothing has to be done for server <s> regarding queued connections,
@@ -87,7 +87,7 @@ static inline int server_has_room(const struct server *s) {
  */
 static inline int may_dequeue_tasks(const struct server *s, const struct proxy *p) {
        return (s && (s->queues_not_empty || (p->queues_not_empty && srv_currently_usable(s))) &&
-               (!s->maxconn || s->cur_sess < srv_dynamic_maxconn(s)));
+               (!s->maxconn || s->served < srv_dynamic_maxconn(s)));
 }
 
 static inline int queue_limit_class(int class)
index d820caca1579a6f9ae8ee7f22fc54893c5a09978..eaede6890de0c3e07b95f7118b0eeda8ba0a809a 100644 (file)
@@ -430,7 +430,6 @@ struct server {
 
        /* usually atomically updated by any thread during parsing or on end of request */
        THREAD_ALIGN();
-       int cur_sess;                           /* number of currently active sessions (including syn_sent) */
        int served;                             /* # of active sessions currently being served (ie not pending) */
        int consecutive_errors;                 /* current number of consecutive errors */
        int consecutive_errors_limit;           /* number of consecutive errors that triggers an event */
index 259a25381d6bb0676029434840d24091d2265205..3ed03dd414adbde6d60b3e002a8e6476a81a9665 100644 (file)
@@ -984,6 +984,7 @@ int assign_server_and_queue(struct stream *s)
 {
        struct pendconn *p;
        struct server *srv;
+       int count;
        int err;
 
        if (s->pend_pos)
@@ -1073,6 +1074,7 @@ int assign_server_and_queue(struct stream *s)
                                                                &served, served + 1);
                                } while (!got_it && served < srv_dynamic_maxconn(srv) &&
                                         __ha_cpu_relax());
+                               count = served + 1;
                        }
                        if (!got_it) {
                                if (srv->maxqueue > 0 && srv->queueslength >= srv->maxqueue)
@@ -1095,8 +1097,9 @@ int assign_server_and_queue(struct stream *s)
                                        return SRV_STATUS_INTERNAL;
                        }
                } else
-                       _HA_ATOMIC_INC(&srv->served);
+                       count = _HA_ATOMIC_ADD_FETCH(&srv->served, 1);
 
+               HA_ATOMIC_UPDATE_MAX(&srv->counters.cur_sess_max, count);
                /* OK, we can use this server. Let's reserve our place */
                sess_change_server(s, srv);
                return SRV_STATUS_OK;
@@ -2273,11 +2276,7 @@ int connect_server(struct stream *s)
        s->conn_exp = tick_add_ifset(now_ms, s->connect_timeout);
 
        if (srv) {
-               int count;
-
                s->flags |= SF_CURR_SESS;
-               count = _HA_ATOMIC_ADD_FETCH(&srv->cur_sess, 1);
-               HA_ATOMIC_UPDATE_MAX(&srv->counters.cur_sess_max, count);
                if (s->be->lbprm.server_take_conn)
                        s->be->lbprm.server_take_conn(srv);
        }
@@ -2784,10 +2783,8 @@ void back_handle_st_cer(struct stream *s)
 
                health_adjust(__objt_server(s->target), HANA_STATUS_L4_ERR);
 
-               if (s->flags & SF_CURR_SESS) {
+               if (s->flags & SF_CURR_SESS)
                        s->flags &= ~SF_CURR_SESS;
-                       _HA_ATOMIC_DEC(&__objt_server(s->target)->cur_sess);
-               }
 
                if ((sc->flags & SC_FL_ERROR) &&
                    conn && conn->err_code == CO_ER_SSL_MISMATCH_SNI) {
@@ -3420,7 +3417,7 @@ smp_fetch_connslots(const struct arg *args, struct sample *smp, const char *kw,
                        return 1;
                }
 
-               smp->data.u.sint += (iterator->maxconn - iterator->cur_sess)
+               smp->data.u.sint += (iterator->maxconn - iterator->served)
                                       +  (iterator->maxqueue - iterator->queueslength);
        }
 
@@ -3590,8 +3587,8 @@ smp_fetch_be_conn_free(const struct arg *args, struct sample *smp, const char *k
                }
 
                maxconn = srv_dynamic_maxconn(iterator);
-               if (maxconn > iterator->cur_sess)
-                       smp->data.u.sint += maxconn - iterator->cur_sess;
+               if (maxconn > iterator->served)
+                       smp->data.u.sint += maxconn - iterator->served;
        }
 
        return 1;
@@ -3658,7 +3655,7 @@ smp_fetch_srv_conn(const struct arg *args, struct sample *smp, const char *kw, v
 {
        smp->flags = SMP_F_VOL_TEST;
        smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = args->data.srv->cur_sess;
+       smp->data.u.sint = args->data.srv->served;
        return 1;
 }
 
@@ -3681,8 +3678,8 @@ smp_fetch_srv_conn_free(const struct arg *args, struct sample *smp, const char *
        }
 
        maxconn = srv_dynamic_maxconn(args->data.srv);
-       if (maxconn > args->data.srv->cur_sess)
-               smp->data.u.sint = maxconn - args->data.srv->cur_sess;
+       if (maxconn > args->data.srv->served)
+               smp->data.u.sint = maxconn - args->data.srv->served;
        else
                smp->data.u.sint = 0;
 
index afcd27b3ef7e6e3e65ae5b9c5a18c16f0fabd21f..7dc6b03d3fc29d5fe2798e7eb58446ad5c1a94ce 100644 (file)
@@ -1029,7 +1029,7 @@ int httpchk_build_status_header(struct server *s, struct buffer *buf)
                      global.node,
                      (s->cur_eweight * s->proxy->lbprm.wmult + s->proxy->lbprm.wdiv - 1) / s->proxy->lbprm.wdiv,
                      (s->proxy->lbprm.tot_weight * s->proxy->lbprm.wmult + s->proxy->lbprm.wdiv - 1) / s->proxy->lbprm.wdiv,
-                     s->cur_sess, s->proxy->beconn - s->proxy->queueslength,
+                     s->served, s->proxy->beconn - s->proxy->queueslength,
                      s->queueslength);
 
        if ((s->cur_state == SRV_ST_STARTING) &&
index ab5a008f37f0db71d7513b58aade2e98a6aa6ebc..8fac95e4e4b0bf45261f1a0394855241c3b5bee5 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -3536,7 +3536,6 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                if (objt_server(s->target)) {
                        if (s->flags & SF_CURR_SESS) {
                                s->flags &= ~SF_CURR_SESS;
-                               HA_ATOMIC_DEC(&__objt_server(s->target)->cur_sess);
                        }
                        if (may_dequeue_tasks(__objt_server(s->target), be))
                                process_srv_queue(__objt_server(s->target));
index 152acaddc794748eb23f7a44b77fed809ff5f9f0..4b4257d6352a2ff0c97c82ce6a04d7f1af9dc115 100644 (file)
@@ -342,7 +342,7 @@ int prepare_external_check(struct check *check)
        EXTCHK_SETENV(check, EXTCHK_HAPROXY_SERVER_ADDR, check->argv[3], err);
        EXTCHK_SETENV(check, EXTCHK_HAPROXY_SERVER_PORT, check->argv[4], err);
        EXTCHK_SETENV(check, EXTCHK_HAPROXY_SERVER_MAXCONN, ultoa_r(s->maxconn, buf, sizeof(buf)), err);
-       EXTCHK_SETENV(check, EXTCHK_HAPROXY_SERVER_CURCONN, ultoa_r(s->cur_sess, buf, sizeof(buf)), err);
+       EXTCHK_SETENV(check, EXTCHK_HAPROXY_SERVER_CURCONN, ultoa_r(s->served, buf, sizeof(buf)), err);
        EXTCHK_SETENV(check, EXTCHK_HAPROXY_SERVER_SSL, s->use_ssl ? "1" : "0", err);
 
        switch (px->mode) {
@@ -438,7 +438,7 @@ static int connect_proc_chk(struct task *t)
                }
 
                /* Update some environment variables and command args: curconn, server addr and server port */
-               EXTCHK_SETENV(check, EXTCHK_HAPROXY_SERVER_CURCONN, ultoa_r(s->cur_sess, buf, sizeof(buf)), fail);
+               EXTCHK_SETENV(check, EXTCHK_HAPROXY_SERVER_CURCONN, ultoa_r(s->served, buf, sizeof(buf)), fail);
 
                family = real_family(s->addr.ss_family);
                if (family == AF_UNIX) {
index 49640f6ebb74bb010fb20ab1a533205d2e5db9ff..71cdb1d7019310a2426b841c84ece64e5bd420f5 100644 (file)
@@ -905,7 +905,7 @@ static void sig_dump_state(struct sig_handler *sh)
                                     "SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %llu tot.",
                                     p->id, s->id,
                                     (s->cur_state != SRV_ST_STOPPED) ? "UP" : "DOWN",
-                                    s->cur_sess, s->queueslength, (ullong)COUNTERS_SHARED_TOTAL(s->counters.shared.tg, cum_sess, HA_ATOMIC_LOAD));
+                                    s->served, s->queueslength, (ullong)COUNTERS_SHARED_TOTAL(s->counters.shared.tg, cum_sess, HA_ATOMIC_LOAD));
                        ha_warning("%s\n", trash.area);
                        send_log(p, LOG_NOTICE, "%s\n", trash.area);
                        s = s->next;
index 6fc0d5d8bb4eafbd1a3f7dd3ecbab550d9b9cac4..06cb7bffce378949209a90b8c1c0a99593bf1dd5 100644 (file)
@@ -1394,7 +1394,7 @@ int hlua_server_get_cur_sess(lua_State *L)
                return 1;
        }
 
-       lua_pushinteger(L, srv->cur_sess);
+       lua_pushinteger(L, srv->served);
        return 1;
 }
 
index f004e41d94776a9548ed23887781cf4981d15b32..b8bba27d916d4c5fd733854970292f618df29164 100644 (file)
@@ -1191,10 +1191,9 @@ static __inline int do_l7_retry(struct stream *s, struct stconn *sc)
                return -1;
        s->conn_retries++;
        if (objt_server(s->target)) {
-               if (s->flags & SF_CURR_SESS) {
+               if (s->flags & SF_CURR_SESS)
                        s->flags &= ~SF_CURR_SESS;
-                       _HA_ATOMIC_DEC(&__objt_server(s->target)->cur_sess);
-               }
+
                if (s->sv_tgcounters)
                        _HA_ATOMIC_INC(&s->sv_tgcounters->retries);
        }
index 9fc0d86aa5d3e578e119e5a8ff79e3a8af9324f7..d1aa589bd3a2397946c0cc01ce9614dbfcc08469 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -4709,11 +4709,11 @@ int sess_build_logline_orig(struct session *sess, struct stream *s,
 
                                switch (obj_type(s ? s->target : sess->origin)) {
                                case OBJ_TYPE_SERVER:
-                                       value = __objt_server(s->target)->cur_sess;
+                                       value = __objt_server(s->target)->served;
                                        break;
                                case OBJ_TYPE_CHECK:
                                        value = (__objt_check(sess->origin)->server
-                                                ? __objt_check(sess->origin)->server->cur_sess
+                                                ? __objt_check(sess->origin)->server->served
                                                 : 0);
                                        break;
                                default:
index 819ab3dd09bb85fddf1fe1e740b46dc5b8fb7b17..5a340e53b75bfe6d21f3ae1de8c2ef4ec06bea76 100644 (file)
@@ -2157,7 +2157,7 @@ static void srv_append_more(struct buffer *msg, struct server *s,
                                " %d sessions active, %d requeued, %d remaining in queue",
                                s->proxy->srv_act, s->proxy->srv_bck,
                                (s->proxy->srv_bck && !s->proxy->srv_act) ? " Running on backup." : "",
-                               s->cur_sess, xferred, s->queueslength);
+                               s->served, xferred, s->queueslength);
                else
                        chunk_appendf(msg, ". %d active and %d backup servers online.%s"
                                " %d sessions requeued, %d total in queue",
index 278a4bf9c7694a63d761d37edfc665ccec41272f..5ae60d72235d425c1550ff0b62d8e1ac4fbc5964 100644 (file)
@@ -863,7 +863,7 @@ int stats_fill_sv_line(struct proxy *px, struct server *sv, int flags,
                                field = mkf_u32(FN_MAX, sv->counters.nbpend_max);
                                break;
                        case ST_I_PX_SCUR:
-                               field = mkf_u32(0, sv->cur_sess);
+                               field = mkf_u32(0, sv->served);
                                break;
                        case ST_I_PX_SMAX:
                                field = mkf_u32(FN_MAX, sv->counters.cur_sess_max);
index 40c58e32594171aeb342ae4aacda5504887cdb87..45877d7d84207301dc93b1c446d36fea6ab69f43 100644 (file)
@@ -630,10 +630,9 @@ void stream_free(struct stream *s)
        pendconn_free(s);
 
        if (objt_server(s->target)) { /* there may be requests left pending in queue */
-               if (s->flags & SF_CURR_SESS) {
+               if (s->flags & SF_CURR_SESS)
                        s->flags &= ~SF_CURR_SESS;
-                       _HA_ATOMIC_DEC(&__objt_server(s->target)->cur_sess);
-               }
+
                if (may_dequeue_tasks(__objt_server(s->target), s->be))
                        process_srv_queue(__objt_server(s->target));
        }
@@ -2057,10 +2056,9 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                scb->state = SC_ST_CLO;
                srv = objt_server(s->target);
                if (srv) {
-                       if (s->flags & SF_CURR_SESS) {
+                       if (s->flags & SF_CURR_SESS)
                                s->flags &= ~SF_CURR_SESS;
-                               _HA_ATOMIC_DEC(&srv->cur_sess);
-                       }
+
                        /*
                         * We don't want to release the slot just yet
                         * if we're using strict-maxconn, we want to
@@ -2982,10 +2980,8 @@ void stream_shutdown_self(struct stream *stream, int why)
                stream->flags |= why;
 
        if (objt_server(stream->target)) {
-               if (stream->flags & SF_CURR_SESS) {
+               if (stream->flags & SF_CURR_SESS)
                        stream->flags &= ~SF_CURR_SESS;
-                       _HA_ATOMIC_DEC(&__objt_server(stream->target)->cur_sess);
-               }
 
                sess_change_server(stream, NULL);
                if (may_dequeue_tasks(objt_server(stream->target), stream->be))