]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MAJOR: counters: add shared counters base infrastructure
authorAurelien DARRAGON <adarragon@haproxy.com>
Tue, 8 Apr 2025 16:16:38 +0000 (18:16 +0200)
committerAurelien DARRAGON <adarragon@haproxy.com>
Thu, 5 Jun 2025 07:58:58 +0000 (09:58 +0200)
Shareable counters are not tagged as shared counters and are dynamically
allocated in separate memory area as a prerequisite for being stored
in shared memory area. For now, GUID and threads groups are not taken into
account, this is only a first step.

also we ensure all counters are now manipulated using atomic operations,
namely, "last_change" counter is now read from and written to using atomic
ops.

Despite the numerous changes caused by the counters being moved away from
counters struct, no change of behavior should be expected.

29 files changed:
include/haproxy/backend.h
include/haproxy/counters-t.h
include/haproxy/proxy.h
include/haproxy/server.h
include/haproxy/stats-t.h
include/haproxy/stream.h
src/backend.c
src/cache.c
src/cfgparse.c
src/check.c
src/fcgi-app.c
src/flt_http_comp.c
src/frontend.c
src/haproxy.c
src/hlua.c
src/http_act.c
src/http_ana.c
src/listener.c
src/log.c
src/mux_h1.c
src/proxy.c
src/queue.c
src/server.c
src/server_state.c
src/stats-file.c
src/stats-proxy.c
src/stream.c
src/tcp_act.c
src/tcp_rules.c

index 01b0cbdcbeef4c9e7fe6d5396a2ae42a4523e080..c8b68d11f532b84c6ed645475e449b9c3f0a4dab 100644 (file)
@@ -86,7 +86,7 @@ static inline int be_usable_srv(struct proxy *be)
 /* set the time of last session on the backend */
 static inline void be_set_sess_last(struct proxy *be)
 {
-       be->be_counters.last_sess = ns_to_sec(now_ns);
+       HA_ATOMIC_STORE(&be->be_counters.shared->last_sess, ns_to_sec(now_ns));
 }
 
 /* This function returns non-zero if the designated server will be
index 8539d6c22126de2e6ca05cd4198921e4cc5d29d5..a91d88e88e5d3d26199d6d592486259339db7f53 100644 (file)
 #include <haproxy/freq_ctr-t.h>
 
 /* counters used by listeners and frontends */
-struct fe_counters {
-       unsigned int conn_max;                  /* max # of active sessions */
+struct fe_counters_shared {
+       long long internal_errors;              /* internal processing errors */
+       long long failed_rewrites;              /* failed rewrites (warning) */
+       long long denied_sess;                  /* denied session requests (tcp-req-sess rules) */
+       long long denied_conn;                  /* denied connection requests (tcp-req-conn rules) */
+       long long intercepted_req;              /* number of monitoring or stats requests intercepted by the frontend */
        long long    cum_conn;                  /* cumulated number of received connections */
-       long long    cum_sess;                  /* cumulated number of accepted connections */
-       long long    cum_sess_ver[3];           /* cumulated number of h1/h2/h3 sessions */
-
-       unsigned int cps_max;                   /* maximum of new connections received per second */
-       unsigned int sps_max;                   /* maximum of new connections accepted per second (sessions) */
-
-       long long bytes_in;                     /* number of bytes transferred from the client to the server */
-       long long bytes_out;                    /* number of bytes transferred from the server to the client */
+       struct freq_ctr conn_per_sec;           /* received connections per second on the frontend */
 
        /* compression counters, index 0 for requests, 1 for responses */
        long long comp_in[2];                   /* input bytes fed to the compressor */
        long long comp_out[2];                  /* output bytes emitted by the compressor */
        long long comp_byp[2];                  /* input bytes that bypassed the compressor (cpu/ram/bw limitation) */
 
-       long long denied_req;                   /* blocked requests because of security concerns */
-       long long denied_resp;                  /* blocked responses because of security concerns */
-       long long failed_req;                   /* failed requests (eg: invalid or timeout) */
-       long long denied_conn;                  /* denied connection requests (tcp-req-conn rules) */
-       long long denied_sess;                  /* denied session requests (tcp-req-sess rules) */
-       long long failed_rewrites;              /* failed rewrites (warning) */
-       long long internal_errors;              /* internal processing errors */
 
-       long long cli_aborts;                   /* aborted responses during DATA phase caused by the client */
        long long srv_aborts;                   /* aborted responses during DATA phase caused by the server */
-       long long intercepted_req;              /* number of monitoring or stats requests intercepted by the frontend */
+       long long cli_aborts;                   /* aborted responses during DATA phase caused by the client */
+
+
+       struct freq_ctr req_per_sec;            /* HTTP requests per second on the frontend */
 
+       long long    cum_sess_ver[3];           /* cumulated number of h1/h2/h3 sessions */
        union {
                struct {
                        long long cum_req[4];   /* cumulated number of processed other/h1/h2/h3 requests */
+                       long long cache_hits;   /* cache hits */
+                       long long cache_lookups;/* cache lookups */
                        long long comp_rsp;     /* number of compressed responses */
-                       unsigned int rps_max;   /* maximum of new HTTP requests second observed */
                        long long rsp[6];       /* http response codes */
-                       long long cache_lookups;/* cache lookups */
-                       long long cache_hits;   /* cache hits */
+
+
                } http;
        } p;                                    /* protocol-specific stats */
-
        struct freq_ctr sess_per_sec;           /* sessions per second on this server */
-       struct freq_ctr req_per_sec;            /* HTTP requests per second on the frontend */
-       struct freq_ctr conn_per_sec;           /* received connections per second on the frontend */
-
        unsigned long last_change;              /* last time, when the state was changed */
+
+       long long failed_req;                   /* failed requests (eg: invalid or timeout) */
+       long long denied_resp;                  /* blocked responses because of security concerns */
+       long long denied_req;                   /* blocked requests because of security concerns */
+
+       long long bytes_out;                    /* number of bytes transferred from the server to the client */
+       long long bytes_in;                     /* number of bytes transferred from the client to the server */
+       long long    cum_sess;                  /* cumulated number of accepted connections */
 };
 
-/* counters used by servers and backends */
-struct be_counters {
+struct fe_counters {
+       struct fe_counters_shared *shared;      /* shared counters */
        unsigned int conn_max;                  /* max # of active sessions */
-       long long    cum_sess;                  /* cumulated number of accepted connections */
-       long long  cum_lbconn;                  /* cumulated number of sessions processed by load balancing (BE only) */
 
        unsigned int cps_max;                   /* maximum of new connections received per second */
        unsigned int sps_max;                   /* maximum of new connections accepted per second (sessions) */
-       unsigned int nbpend_max;                /* max number of pending connections with no server assigned yet */
-       unsigned int cur_sess_max;              /* max number of currently active sessions */
 
-       long long bytes_in;                     /* number of bytes transferred from the client to the server */
-       long long bytes_out;                    /* number of bytes transferred from the server to the client */
+       union {
+               struct {
+                       unsigned int rps_max;   /* maximum of new HTTP requests second observed */
+               } http;
+       } p;                                    /* protocol-specific stats */
+};
+
+struct be_counters_shared {
+       long long internal_errors;              /* internal processing errors */
+
+       long long  cum_lbconn;                  /* cumulated number of sessions processed by load balancing (BE only) */
+
+       long long connect;                      /* number of connection establishment attempts */
+       long long reuse;                        /* number of connection reuses */
+       long long failed_rewrites;              /* failed rewrites (warning) */
+       unsigned long last_sess;                /* last session time */
 
        /* compression counters, index 0 for requests, 1 for responses */
        long long comp_in[2];                   /* input bytes fed to the compressor */
        long long comp_out[2];                  /* output bytes emitted by the compressor */
        long long comp_byp[2];                  /* input bytes that bypassed the compressor (cpu/ram/bw limitation) */
 
-       long long denied_req;                   /* blocked requests because of security concerns */
-       long long denied_resp;                  /* blocked responses because of security concerns */
-
-       long long connect;                      /* number of connection establishment attempts */
-       long long reuse;                        /* number of connection reuses */
-       long long failed_conns;                 /* failed connect() attempts (BE only) */
-       long long failed_resp;                  /* failed responses (BE only) */
-       long long cli_aborts;                   /* aborted responses during DATA phase caused by the client */
        long long srv_aborts;                   /* aborted responses during DATA phase caused by the server */
-       long long retries;                      /* retried and redispatched connections (BE only) */
-       long long redispatches;                 /* retried and redispatched connections (BE only) */
-       long long failed_rewrites;              /* failed rewrites (warning) */
-       long long internal_errors;              /* internal processing errors */
+       long long cli_aborts;                   /* aborted responses during DATA phase caused by the client */
 
        long long failed_checks, failed_hana;   /* failed health checks and health analyses for servers */
        long long down_trans;                   /* up->down transitions */
 
-       unsigned int q_time, c_time, d_time, t_time; /* sums of conn_time, queue_time, data_time, total_time */
-       unsigned int qtime_max, ctime_max, dtime_max, ttime_max; /* maximum of conn_time, queue_time, data_time, total_time observed */
-
        union {
                struct {
                        long long cum_req;      /* cumulated number of processed HTTP requests */
+
+                       long long cache_hits;   /* cache hits */
+                       long long cache_lookups;/* cache lookups */
                        long long comp_rsp;     /* number of compressed responses */
-                       unsigned int rps_max;   /* maximum of new HTTP requests second observed */
                        long long rsp[6];       /* http response codes */
-                       long long cache_lookups;/* cache lookups */
-                       long long cache_hits;   /* cache hits */
+
                } http;
        } p;                                    /* protocol-specific stats */
-
        struct freq_ctr sess_per_sec;           /* sessions per second on this server */
 
-       unsigned long last_sess;                /* last session time */
+       long long redispatches;                 /* retried and redispatched connections (BE only) */
+       long long retries;                      /* retried and redispatched connections (BE only) */
+       long long failed_resp;                  /* failed responses (BE only) */
+
+       long long failed_conns;                 /* failed connect() attempts (BE only) */
+       long long denied_resp;                  /* blocked responses because of security concerns */
+
+       long long denied_req;                   /* blocked requests because of security concerns */
+       long long bytes_out;                    /* number of bytes transferred from the server to the client */
+       long long bytes_in;                     /* number of bytes transferred from the client to the server */
+
+       long long    cum_sess;                  /* cumulated number of accepted connections */
+
        unsigned long last_change;              /* last time, when the state was changed */
 };
 
+/* counters used by servers and backends */
+struct be_counters {
+       struct be_counters_shared *shared;      /* shared counters */
+       unsigned int conn_max;                  /* max # of active sessions */
+
+       unsigned int cps_max;                   /* maximum of new connections received per second */
+       unsigned int sps_max;                   /* maximum of new connections accepted per second (sessions) */
+       unsigned int nbpend_max;                /* max number of pending connections with no server assigned yet */
+       unsigned int cur_sess_max;              /* max number of currently active sessions */
+
+       unsigned int q_time, c_time, d_time, t_time; /* sums of conn_time, queue_time, data_time, total_time */
+       unsigned int qtime_max, ctime_max, dtime_max, ttime_max; /* maximum of conn_time, queue_time, data_time, total_time observed */
+
+       union {
+               struct {
+                       unsigned int rps_max;   /* maximum of new HTTP requests second observed */
+               } http;
+       } p;                                    /* protocol-specific stats */
+};
+
 #endif /* _HAPROXY_COUNTERS_T_H */
 
 /*
index 43e9758606d1c77cff6423f3568f47706e41551f..e2eaa2baca9986cacc09d48e127954d50b0ab6d4 100644 (file)
@@ -136,22 +136,22 @@ static inline void proxy_reset_timeouts(struct proxy *proxy)
 /* increase the number of cumulated connections received on the designated frontend */
 static inline void proxy_inc_fe_conn_ctr(struct listener *l, struct proxy *fe)
 {
-       _HA_ATOMIC_INC(&fe->fe_counters.cum_conn);
+       _HA_ATOMIC_INC(&fe->fe_counters.shared->cum_conn);
        if (l && l->counters)
-               _HA_ATOMIC_INC(&l->counters->cum_conn);
+               _HA_ATOMIC_INC(&l->counters->shared->cum_conn);
        HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.cps_max,
-                            update_freq_ctr(&fe->fe_counters.conn_per_sec, 1));
+                            update_freq_ctr(&fe->fe_counters.shared->conn_per_sec, 1));
 }
 
 /* increase the number of cumulated connections accepted by the designated frontend */
 static inline void proxy_inc_fe_sess_ctr(struct listener *l, struct proxy *fe)
 {
 
-       _HA_ATOMIC_INC(&fe->fe_counters.cum_sess);
+       _HA_ATOMIC_INC(&fe->fe_counters.shared->cum_sess);
        if (l && l->counters)
-               _HA_ATOMIC_INC(&l->counters->cum_sess);
+               _HA_ATOMIC_INC(&l->counters->shared->cum_sess);
        HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.sps_max,
-                            update_freq_ctr(&fe->fe_counters.sess_per_sec, 1));
+                            update_freq_ctr(&fe->fe_counters.shared->sess_per_sec, 1));
 }
 
 /* increase the number of cumulated HTTP sessions on the designated frontend.
@@ -161,20 +161,20 @@ static inline void proxy_inc_fe_cum_sess_ver_ctr(struct listener *l, struct prox
                                                  unsigned int http_ver)
 {
        if (http_ver == 0 ||
-           http_ver > sizeof(fe->fe_counters.cum_sess_ver) / sizeof(*fe->fe_counters.cum_sess_ver))
+           http_ver > sizeof(fe->fe_counters.shared->cum_sess_ver) / sizeof(*fe->fe_counters.shared->cum_sess_ver))
            return;
 
-       _HA_ATOMIC_INC(&fe->fe_counters.cum_sess_ver[http_ver - 1]);
+       _HA_ATOMIC_INC(&fe->fe_counters.shared->cum_sess_ver[http_ver - 1]);
        if (l && l->counters)
-               _HA_ATOMIC_INC(&l->counters->cum_sess_ver[http_ver - 1]);
+               _HA_ATOMIC_INC(&l->counters->shared->cum_sess_ver[http_ver - 1]);
 }
 
 /* increase the number of cumulated streams on the designated backend */
 static inline void proxy_inc_be_ctr(struct proxy *be)
 {
-       _HA_ATOMIC_INC(&be->be_counters.cum_sess);
+       _HA_ATOMIC_INC(&be->be_counters.shared->cum_sess);
        HA_ATOMIC_UPDATE_MAX(&be->be_counters.sps_max,
-                            update_freq_ctr(&be->be_counters.sess_per_sec, 1));
+                            update_freq_ctr(&be->be_counters.shared->sess_per_sec, 1));
 }
 
 /* increase the number of cumulated requests on the designated frontend.
@@ -184,14 +184,14 @@ static inline void proxy_inc_be_ctr(struct proxy *be)
 static inline void proxy_inc_fe_req_ctr(struct listener *l, struct proxy *fe,
                                         unsigned int http_ver)
 {
-       if (http_ver >= sizeof(fe->fe_counters.p.http.cum_req) / sizeof(*fe->fe_counters.p.http.cum_req))
+       if (http_ver >= sizeof(fe->fe_counters.shared->p.http.cum_req) / sizeof(*fe->fe_counters.shared->p.http.cum_req))
            return;
 
-       _HA_ATOMIC_INC(&fe->fe_counters.p.http.cum_req[http_ver]);
+       _HA_ATOMIC_INC(&fe->fe_counters.shared->p.http.cum_req[http_ver]);
        if (l && l->counters)
-               _HA_ATOMIC_INC(&l->counters->p.http.cum_req[http_ver]);
+               _HA_ATOMIC_INC(&l->counters->shared->p.http.cum_req[http_ver]);
        HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.p.http.rps_max,
-                            update_freq_ctr(&fe->fe_counters.req_per_sec, 1));
+                            update_freq_ctr(&fe->fe_counters.shared->req_per_sec, 1));
 }
 
 /* Returns non-zero if the proxy is configured to retry a request if we got that status, 0 otherwise */
index deb6ec2f7d86d1b87638028a87342b63565cd531..61ece11a2bd98c60e1b05dfeaca57bcf41ed1c07 100644 (file)
@@ -181,15 +181,15 @@ const struct mux_ops *srv_get_ws_proto(struct server *srv);
 /* increase the number of cumulated streams on the designated server */
 static inline void srv_inc_sess_ctr(struct server *s)
 {
-       _HA_ATOMIC_INC(&s->counters.cum_sess);
+       _HA_ATOMIC_INC(&s->counters.shared->cum_sess);
        HA_ATOMIC_UPDATE_MAX(&s->counters.sps_max,
-                            update_freq_ctr(&s->counters.sess_per_sec, 1));
+                            update_freq_ctr(&s->counters.shared->sess_per_sec, 1));
 }
 
 /* set the time of last session on the designated server */
 static inline void srv_set_sess_last(struct server *s)
 {
-       s->counters.last_sess = ns_to_sec(now_ns);
+       HA_ATOMIC_STORE(&s->counters.shared->last_sess,  ns_to_sec(now_ns));
 }
 
 /* returns the current server throttle rate between 0 and 100% */
index 7a320c92192137409925eac3fe1c5cc612cd1453..465bbe06816de22383ee0d1c896a219e062c28f1 100644 (file)
@@ -345,6 +345,7 @@ enum stat_idx_info {
 /* Flags for stat_col.flags */
 #define STAT_COL_FL_NONE    0x00
 #define STAT_COL_FL_GENERIC 0x01        /* stat is generic if set */
+#define STAT_COL_FL_SHARED  0x02        /* stat may be shared between co-processes if set */
 
 /* Represent an exposed statistic. */
 struct stat_col {
index 2212d6450fc38a2ca00c5931e634a26a45b7d7fa..6834faa6d724059cbff9f71e2debcf2bff87fb6b 100644 (file)
@@ -362,8 +362,8 @@ static inline void stream_choose_redispatch(struct stream *s)
                s->scb->state = SC_ST_REQ;
        } else {
                if (objt_server(s->target))
-                       _HA_ATOMIC_INC(&__objt_server(s->target)->counters.retries);
-               _HA_ATOMIC_INC(&s->be->be_counters.retries);
+                       _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->retries);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->retries);
                s->scb->state = SC_ST_ASS;
        }
 
index 0c824e668448b68bf74613a53525bf11e35653e4..72de6e5e91af42c49eabdeb5e8b27e4735958895 100644 (file)
@@ -824,8 +824,8 @@ int assign_server(struct stream *s)
                        goto out;
                }
                else if (srv != prev_srv) {
-                       _HA_ATOMIC_INC(&s->be->be_counters.cum_lbconn);
-                       _HA_ATOMIC_INC(&srv->counters.cum_lbconn);
+                       _HA_ATOMIC_INC(&s->be->be_counters.shared->cum_lbconn);
+                       _HA_ATOMIC_INC(&srv->counters.shared->cum_lbconn);
                }
                s->target = &srv->obj_type;
        }
@@ -999,11 +999,11 @@ int assign_server_and_queue(struct stream *s)
                                        s->txn->flags |= TX_CK_DOWN;
                                }
                                s->flags |= SF_REDISP;
-                               _HA_ATOMIC_INC(&prev_srv->counters.redispatches);
-                               _HA_ATOMIC_INC(&s->be->be_counters.redispatches);
+                               _HA_ATOMIC_INC(&prev_srv->counters.shared->redispatches);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->redispatches);
                        } else {
-                               _HA_ATOMIC_INC(&prev_srv->counters.retries);
-                               _HA_ATOMIC_INC(&s->be->be_counters.retries);
+                               _HA_ATOMIC_INC(&prev_srv->counters.shared->retries);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->retries);
                        }
                }
        }
@@ -2084,13 +2084,13 @@ int connect_server(struct stream *s)
                s->scb->flags |= SC_FL_NOLINGER;
 
        if (s->flags & SF_SRV_REUSED) {
-               _HA_ATOMIC_INC(&s->be->be_counters.reuse);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->reuse);
                if (srv)
-                       _HA_ATOMIC_INC(&srv->counters.reuse);
+                       _HA_ATOMIC_INC(&srv->counters.shared->reuse);
        } else {
-               _HA_ATOMIC_INC(&s->be->be_counters.connect);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->connect);
                if (srv)
-                       _HA_ATOMIC_INC(&srv->counters.connect);
+                       _HA_ATOMIC_INC(&srv->counters.shared->connect);
        }
 
        err = do_connect_server(s, srv_conn);
@@ -2279,8 +2279,8 @@ int srv_redispatch_connect(struct stream *s)
                        s->conn_err_type = STRM_ET_QUEUE_ERR;
                }
 
-               _HA_ATOMIC_INC(&srv->counters.failed_conns);
-               _HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
+               _HA_ATOMIC_INC(&srv->counters.shared->failed_conns);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_conns);
                return 1;
 
        case SRV_STATUS_NOSRV:
@@ -2289,7 +2289,7 @@ int srv_redispatch_connect(struct stream *s)
                        s->conn_err_type = STRM_ET_CONN_ERR;
                }
 
-               _HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_conns);
                return 1;
 
        case SRV_STATUS_QUEUED:
@@ -2318,8 +2318,8 @@ int srv_redispatch_connect(struct stream *s)
                if (srv)
                        srv_set_sess_last(srv);
                if (srv)
-                       _HA_ATOMIC_INC(&srv->counters.failed_conns);
-               _HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
+                       _HA_ATOMIC_INC(&srv->counters.shared->failed_conns);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_conns);
 
                /* release other streams waiting for this server */
                if (may_dequeue_tasks(srv, s->be))
@@ -2393,8 +2393,8 @@ void back_try_conn_req(struct stream *s)
                        if (srv)
                                srv_set_sess_last(srv);
                        if (srv)
-                               _HA_ATOMIC_INC(&srv->counters.failed_conns);
-                       _HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
+                               _HA_ATOMIC_INC(&srv->counters.shared->failed_conns);
+                       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_conns);
 
                        /* release other streams waiting for this server */
                        sess_change_server(s, NULL);
@@ -2460,8 +2460,8 @@ void back_try_conn_req(struct stream *s)
                        pendconn_cond_unlink(s->pend_pos);
 
                        if (srv)
-                               _HA_ATOMIC_INC(&srv->counters.failed_conns);
-                       _HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
+                               _HA_ATOMIC_INC(&srv->counters.shared->failed_conns);
+                       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_conns);
                        sc_abort(sc);
                        sc_shutdown(sc);
                        req->flags |= CF_WRITE_TIMEOUT;
@@ -2716,8 +2716,8 @@ void back_handle_st_cer(struct stream *s)
                }
 
                if (objt_server(s->target))
-                       _HA_ATOMIC_INC(&objt_server(s->target)->counters.failed_conns);
-               _HA_ATOMIC_INC(&s->be->be_counters.failed_conns);
+                       _HA_ATOMIC_INC(&objt_server(s->target)->counters.shared->failed_conns);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_conns);
                sess_change_server(s, NULL);
                if (may_dequeue_tasks(objt_server(s->target), s->be))
                        process_srv_queue(objt_server(s->target));
@@ -2749,8 +2749,8 @@ void back_handle_st_cer(struct stream *s)
                        s->conn_err_type = STRM_ET_CONN_OTHER;
 
                if (objt_server(s->target))
-                       _HA_ATOMIC_INC(&objt_server(s->target)->counters.internal_errors);
-               _HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
+                       _HA_ATOMIC_INC(&objt_server(s->target)->counters.shared->internal_errors);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->internal_errors);
                sess_change_server(s, NULL);
                if (may_dequeue_tasks(objt_server(s->target), s->be))
                        process_srv_queue(objt_server(s->target));
@@ -2887,8 +2887,8 @@ void back_handle_st_rdy(struct stream *s)
  */
 void set_backend_down(struct proxy *be)
 {
-       be->be_counters.last_change = ns_to_sec(now_ns);
-       _HA_ATOMIC_INC(&be->be_counters.down_trans);
+       HA_ATOMIC_STORE(&be->be_counters.shared->last_change, ns_to_sec(now_ns));
+       _HA_ATOMIC_INC(&be->be_counters.shared->down_trans);
 
        if (!(global.mode & MODE_STARTING)) {
                ha_alert("%s '%s' has no server available!\n", proxy_type_str(be), be->id);
@@ -2960,10 +2960,12 @@ no_cookie:
 }
 
 int be_downtime(struct proxy *px) {
-       if (px->lbprm.tot_weight && px->be_counters.last_change < ns_to_sec(now_ns))  // ignore negative time
+       unsigned long last_change = HA_ATOMIC_LOAD(&px->be_counters.shared->last_change);
+
+       if (px->lbprm.tot_weight && last_change < ns_to_sec(now_ns))  // ignore negative time
                return px->down_time;
 
-       return ns_to_sec(now_ns) - px->be_counters.last_change + px->down_time;
+       return ns_to_sec(now_ns) - last_change + px->down_time;
 }
 
 /*
@@ -3401,7 +3403,7 @@ smp_fetch_be_sess_rate(const struct arg *args, struct sample *smp, const char *k
 
        smp->flags = SMP_F_VOL_TEST;
        smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = read_freq_ctr(&px->be_counters.sess_per_sec);
+       smp->data.u.sint = read_freq_ctr(&px->be_counters.shared->sess_per_sec);
        return 1;
 }
 
@@ -3584,7 +3586,7 @@ smp_fetch_srv_sess_rate(const struct arg *args, struct sample *smp, const char *
 {
        smp->flags = SMP_F_VOL_TEST;
        smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = read_freq_ctr(&args->data.srv->counters.sess_per_sec);
+       smp->data.u.sint = read_freq_ctr(&args->data.srv->counters.shared->sess_per_sec);
        return 1;
 }
 
index 4ef4bc7c3342fd3602bd5086fe2bb0d124948d16..cd414eb5708c50b543ab0abbe4832bf195fd8d92 100644 (file)
@@ -2133,9 +2133,9 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p
                return ACT_RET_CONT;
 
        if (px == strm_fe(s))
-               _HA_ATOMIC_INC(&px->fe_counters.p.http.cache_lookups);
+               _HA_ATOMIC_INC(&px->fe_counters.shared->p.http.cache_lookups);
        else
-               _HA_ATOMIC_INC(&px->be_counters.p.http.cache_lookups);
+               _HA_ATOMIC_INC(&px->be_counters.shared->p.http.cache_lookups);
 
        cache_tree = get_cache_tree_from_hash(cache, read_u32(s->txn->cache_hash));
 
@@ -2222,9 +2222,9 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p
                                 should_send_notmodified_response(cache, htxbuf(&s->req.buf), res);
 
                        if (px == strm_fe(s))
-                               _HA_ATOMIC_INC(&px->fe_counters.p.http.cache_hits);
+                               _HA_ATOMIC_INC(&px->fe_counters.shared->p.http.cache_hits);
                        else
-                               _HA_ATOMIC_INC(&px->be_counters.p.http.cache_hits);
+                               _HA_ATOMIC_INC(&px->be_counters.shared->p.http.cache_hits);
                        return ACT_RET_CONT;
                } else {
                        s->target = NULL;
index 887669a43d275ecdb1235943eacd64e7ded89632..d8ea334f079d909dae19521104ef8d9a7d5d94f0 100644 (file)
@@ -4258,6 +4258,15 @@ init_proxies_list_stage2:
                        /* enable separate counters */
                        if (curproxy->options2 & PR_O2_SOCKSTAT) {
                                listener->counters = calloc(1, sizeof(*listener->counters));
+                               if (listener->counters) {
+                                       listener->counters->shared = calloc(1, sizeof(*listener->counters->shared));
+                                       if (!listener->counters->shared) {
+                                               ha_free(&listener->counters);
+                                               ha_alert("config: %s '%s': out of memory.\n",
+                                                        proxy_type_str(curproxy), curproxy->id);
+                                       }
+
+                               }
                                if (!listener->name)
                                        memprintf(&listener->name, "sock-%d", listener->luid);
                        }
index b528f8a0262b445db9428c7fe1fa37fcac496467..bac4b3f7344de2d3bfd9e3aec1c9903383f7a00b 100644 (file)
@@ -515,7 +515,7 @@ void set_server_check_status(struct check *check, short status, const char *desc
                if ((!(check->state & CHK_ST_AGENT) ||
                    (check->status >= HCHK_STATUS_L57DATA)) &&
                    (check->health > 0)) {
-                       _HA_ATOMIC_INC(&s->counters.failed_checks);
+                       _HA_ATOMIC_INC(&s->counters.shared->failed_checks);
                        report = 1;
                        check->health--;
                        if (check->health < check->rise)
@@ -743,7 +743,7 @@ void __health_adjust(struct server *s, short status)
        HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
 
        HA_ATOMIC_STORE(&s->consecutive_errors, 0);
-       _HA_ATOMIC_INC(&s->counters.failed_hana);
+       _HA_ATOMIC_INC(&s->counters.shared->failed_hana);
 
        if (s->check.fastinter) {
                /* timer might need to be advanced, it might also already be
@@ -995,6 +995,7 @@ int httpchk_build_status_header(struct server *s, struct buffer *buf)
                                      "UP %d/%d", "UP",
                                      "NOLB %d/%d", "NOLB",
                                      "no check" };
+       unsigned long last_change = HA_ATOMIC_LOAD(&s->counters.shared->last_change);
 
        if (!(s->check.state & CHK_ST_ENABLED))
                sv_state = 6;
@@ -1032,9 +1033,9 @@ int httpchk_build_status_header(struct server *s, struct buffer *buf)
                      s->queueslength);
 
        if ((s->cur_state == SRV_ST_STARTING) &&
-           ns_to_sec(now_ns) < s->counters.last_change + s->slowstart &&
-           ns_to_sec(now_ns) >= s->counters.last_change) {
-               ratio = MAX(1, 100 * (ns_to_sec(now_ns) - s->counters.last_change) / s->slowstart);
+           ns_to_sec(now_ns) < last_change + s->slowstart &&
+           ns_to_sec(now_ns) >= last_change) {
+               ratio = MAX(1, 100 * (ns_to_sec(now_ns) - last_change) / s->slowstart);
                chunk_appendf(buf, "; throttle=%d%%", ratio);
        }
 
index ab5284c50056b1af6b2f4a6686c37268248b4729..fe1f243adeb24db3c9edc3dfb1f97adfbb04286a 100644 (file)
@@ -446,12 +446,12 @@ static int fcgi_flt_http_headers(struct stream *s, struct filter *filter, struct
        goto end;
 
   rewrite_err:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
-       _HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_rewrites);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_rewrites);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_rewrites);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_rewrites);
   hdr_rule_err:
        node = ebpt_first(&hdr_rules);
        while (node) {
index 265e47280fdfbcda577cdb1b0f311cf1bb240430..875078cacef1c387b211d48cf3e2ec288ce843f6 100644 (file)
@@ -393,14 +393,14 @@ comp_http_payload(struct stream *s, struct filter *filter, struct http_msg *msg,
 
        if (st->comp_ctx[dir] && st->comp_ctx[dir]->cur_lvl > 0) {
                update_freq_ctr(&global.comp_bps_in, consumed);
-               _HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.comp_in[dir], consumed);
-               _HA_ATOMIC_ADD(&s->be->be_counters.comp_in[dir], consumed);
+               _HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.shared->comp_in[dir], consumed);
+               _HA_ATOMIC_ADD(&s->be->be_counters.shared->comp_in[dir], consumed);
                update_freq_ctr(&global.comp_bps_out, to_forward);
-               _HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.comp_out[dir], to_forward);
-               _HA_ATOMIC_ADD(&s->be->be_counters.comp_out[dir], to_forward);
+               _HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.shared->comp_out[dir], to_forward);
+               _HA_ATOMIC_ADD(&s->be->be_counters.shared->comp_out[dir], to_forward);
        } else {
-               _HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.comp_byp[dir], consumed);
-               _HA_ATOMIC_ADD(&s->be->be_counters.comp_byp[dir], consumed);
+               _HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.shared->comp_byp[dir], consumed);
+               _HA_ATOMIC_ADD(&s->be->be_counters.shared->comp_byp[dir], consumed);
        }
        return to_forward;
 
@@ -419,9 +419,9 @@ comp_http_end(struct stream *s, struct filter *filter,
                goto end;
 
        if (strm_fe(s)->mode == PR_MODE_HTTP)
-               _HA_ATOMIC_INC(&strm_fe(s)->fe_counters.p.http.comp_rsp);
+               _HA_ATOMIC_INC(&strm_fe(s)->fe_counters.shared->p.http.comp_rsp);
        if ((s->flags & SF_BE_ASSIGNED) && (s->be->mode == PR_MODE_HTTP))
-               _HA_ATOMIC_INC(&s->be->be_counters.p.http.comp_rsp);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->p.http.comp_rsp);
  end:
        return 1;
 }
index 5e3821d76b6748e4d0275abfc1f98491d7b082a0..f0499978bb91e2b20f23ea8ead0221f2bdde9ced 100644 (file)
@@ -260,7 +260,7 @@ smp_fetch_fe_req_rate(const struct arg *args, struct sample *smp, const char *kw
 
        smp->flags = SMP_F_VOL_TEST;
        smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = read_freq_ctr(&px->fe_counters.req_per_sec);
+       smp->data.u.sint = read_freq_ctr(&px->fe_counters.shared->req_per_sec);
        return 1;
 }
 
@@ -280,7 +280,7 @@ smp_fetch_fe_sess_rate(const struct arg *args, struct sample *smp, const char *k
 
        smp->flags = SMP_F_VOL_TEST;
        smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = read_freq_ctr(&px->fe_counters.sess_per_sec);
+       smp->data.u.sint = read_freq_ctr(&px->fe_counters.shared->sess_per_sec);
        return 1;
 }
 
index 08ca84f1ca0c637df255c511ac0f3ed35f4e9b2a..a13f57d15659cf3c8d289f042925abfde51f2d5c 100644 (file)
@@ -818,7 +818,7 @@ static void sig_dump_state(struct sig_handler *sh)
                                     "SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %lld tot.",
                                     p->id, s->id,
                                     (s->cur_state != SRV_ST_STOPPED) ? "UP" : "DOWN",
-                                    s->cur_sess, s->queueslength, s->counters.cum_sess);
+                                    s->cur_sess, s->queueslength, HA_ATOMIC_LOAD(&s->counters.shared->cum_sess));
                        ha_warning("%s\n", trash.area);
                        send_log(p, LOG_NOTICE, "%s\n", trash.area);
                        s = s->next;
@@ -829,19 +829,19 @@ static void sig_dump_state(struct sig_handler *sh)
                        chunk_printf(&trash,
                                     "SIGHUP: Proxy %s has no servers. Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
                                     p->id,
-                                    p->feconn, p->beconn, p->totpend, p->queueslength, p->fe_counters.cum_conn, p->be_counters.cum_sess);
+                                    p->feconn, p->beconn, p->totpend, p->queueslength, HA_ATOMIC_LOAD(&p->fe_counters.shared->cum_conn), HA_ATOMIC_LOAD(&p->be_counters.shared->cum_sess));
                } else if (p->srv_act == 0) {
                        chunk_printf(&trash,
                                     "SIGHUP: Proxy %s %s ! Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
                                     p->id,
                                     (p->srv_bck) ? "is running on backup servers" : "has no server available",
-                                    p->feconn, p->beconn, p->totpend, p->queueslength, p->fe_counters.cum_conn, p->be_counters.cum_sess);
+                                    p->feconn, p->beconn, p->totpend, p->queueslength, HA_ATOMIC_LOAD(&p->fe_counters.shared->cum_conn), HA_ATOMIC_LOAD(&p->be_counters.shared->cum_sess));
                } else {
                        chunk_printf(&trash,
                                     "SIGHUP: Proxy %s has %d active servers and %d backup servers available."
                                     " Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
                                     p->id, p->srv_act, p->srv_bck,
-                                    p->feconn, p->beconn, p->totpend, p->queueslength, p->fe_counters.cum_conn, p->be_counters.cum_sess);
+                                    p->feconn, p->beconn, p->totpend, p->queueslength, HA_ATOMIC_LOAD(&p->fe_counters.shared->cum_conn), HA_ATOMIC_LOAD(&p->be_counters.shared->cum_sess));
                }
                ha_warning("%s\n", trash.area);
                send_log(p, LOG_NOTICE, "%s\n", trash.area);
index 410eaf0ef356ee9aed5cd52b56556ec30ffc3179..9e499408ce49ebecf0bf07b7507825215224f917 100644 (file)
@@ -9070,7 +9070,7 @@ __LJMP static int hlua_txn_done(lua_State *L)
                /* let's log the request time */
                s->logs.request_ts = now_ns;
                if (s->sess->fe == s->be) /* report it if the request was intercepted by the frontend */
-                       _HA_ATOMIC_INC(&s->sess->fe->fe_counters.intercepted_req);
+                       _HA_ATOMIC_INC(&s->sess->fe->fe_counters.shared->intercepted_req);
        }
 
   done:
index ae435da64e904f59dfe930ae3d85ad2e49a0062f..7cf06c22cc46dd70aadb678ca42662872b4e460a 100644 (file)
@@ -116,13 +116,13 @@ static enum act_return http_action_set_req_line(struct act_rule *rule, struct pr
        goto leave;
 
   fail_rewrite:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_rewrites);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_rewrites);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_rewrites);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_rewrites);
 
        if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
                ret = ACT_RET_ERR;
@@ -386,13 +386,13 @@ static enum act_return http_action_normalize_uri(struct act_rule *rule, struct p
        goto leave;
 
   fail_rewrite:
-       _HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_rewrites, 1);
+       _HA_ATOMIC_ADD(&sess->fe->fe_counters.shared->failed_rewrites, 1);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_ADD(&s->be->be_counters.failed_rewrites, 1);
+               _HA_ATOMIC_ADD(&s->be->be_counters.shared->failed_rewrites, 1);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_ADD(&sess->listener->counters->failed_rewrites, 1);
+               _HA_ATOMIC_ADD(&sess->listener->counters->shared->failed_rewrites, 1);
        if (objt_server(s->target))
-               _HA_ATOMIC_ADD(&__objt_server(s->target)->counters.failed_rewrites, 1);
+               _HA_ATOMIC_ADD(&__objt_server(s->target)->counters.shared->failed_rewrites, 1);
 
        if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
                ret = ACT_RET_ERR;
@@ -562,13 +562,13 @@ static enum act_return http_action_replace_uri(struct act_rule *rule, struct pro
        goto leave;
 
   fail_rewrite:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_rewrites);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_rewrites);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_rewrites);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_rewrites);
 
        if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
                ret = ACT_RET_ERR;
@@ -642,13 +642,13 @@ static enum act_return action_http_set_status(struct act_rule *rule, struct prox
                                               struct session *sess, struct stream *s, int flags)
 {
        if (http_res_set_status(rule->arg.http.i, rule->arg.http.str, s) == -1) {
-               _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
+               _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_rewrites);
                if (s->flags & SF_BE_ASSIGNED)
-                       _HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
+                       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_rewrites);
                if (sess->listener && sess->listener->counters)
-                       _HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
+                       _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_rewrites);
                if (objt_server(s->target))
-                       _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
+                       _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_rewrites);
 
                if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
                        if (!(s->flags & SF_ERR_MASK))
@@ -717,10 +717,10 @@ static enum act_return http_action_reject(struct act_rule *rule, struct proxy *p
        s->req.analysers &= AN_REQ_FLT_END;
        s->res.analysers &= AN_RES_FLT_END;
 
-       _HA_ATOMIC_INC(&s->be->be_counters.denied_req);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_req);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->denied_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->denied_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->denied_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->denied_req);
 
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_PRXCOND;
@@ -1281,7 +1281,7 @@ static enum act_return http_action_auth(struct act_rule *rule, struct proxy *px,
        req->analysers &= AN_REQ_FLT_END;
 
        if (s->sess->fe == s->be) /* report it if the request was intercepted by the frontend */
-               _HA_ATOMIC_INC(&s->sess->fe->fe_counters.intercepted_req);
+               _HA_ATOMIC_INC(&s->sess->fe->fe_counters.shared->intercepted_req);
 
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_LOCAL;
@@ -1449,13 +1449,13 @@ static enum act_return http_action_set_header(struct act_rule *rule, struct prox
        goto leave;
 
   fail_rewrite:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_rewrites);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_rewrites);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_rewrites);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_rewrites);
 
        if (!(msg->flags & HTTP_MSGF_SOFT_RW)) {
                ret = ACT_RET_ERR;
@@ -1581,13 +1581,13 @@ static enum act_return http_action_replace_header(struct act_rule *rule, struct
        goto leave;
 
   fail_rewrite:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_rewrites);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_rewrites);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_rewrites);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_rewrites);
 
        if (!(msg->flags & HTTP_MSGF_SOFT_RW)) {
                ret = ACT_RET_ERR;
@@ -2315,7 +2315,7 @@ static enum act_return http_action_return(struct act_rule *rule, struct proxy *p
                req->analysers &= AN_REQ_FLT_END;
 
                if (s->sess->fe == s->be) /* report it if the request was intercepted by the frontend */
-                       _HA_ATOMIC_INC(&s->sess->fe->fe_counters.intercepted_req);
+                       _HA_ATOMIC_INC(&s->sess->fe->fe_counters.shared->intercepted_req);
        }
 
        return ACT_RET_ABRT;
index 43466df6cfd2f13d37533b6e93a6fae7a5b38e12..8b45057408347a6e20f4a44f86c22c4cbaae371c 100644 (file)
@@ -233,7 +233,7 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit)
                        struct acl_cond *cond;
 
                        s->flags |= SF_MONITOR;
-                       _HA_ATOMIC_INC(&sess->fe->fe_counters.intercepted_req);
+                       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->intercepted_req);
 
                        /* Check if we want to fail this monitor request or not */
                        list_for_each_entry(cond, &sess->fe->mon_fail_cond, list) {
@@ -342,17 +342,17 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit)
        txn->status = 500;
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->internal_errors);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->internal_errors);
        stream_report_term_evt(s->scb, strm_tevt_type_internal_err);
        goto return_prx_cond;
 
  return_bad_req:
        txn->status = 400;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_req);
        stream_report_term_evt(s->scb, strm_tevt_type_proto_err);
        /* fall through */
 
@@ -486,7 +486,7 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s
        /* Proceed with the applets now. */
        if (unlikely(objt_applet(s->target))) {
                if (sess->fe == s->be) /* report it if the request was intercepted by the frontend */
-                       _HA_ATOMIC_INC(&sess->fe->fe_counters.intercepted_req);
+                       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->intercepted_req);
 
                if (http_handle_expect_hdr(s, htx, msg) == -1)
                        goto return_int_err;
@@ -562,11 +562,11 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s
        if (!req->analyse_exp)
                req->analyse_exp = tick_add(now_ms, 0);
        stream_inc_http_err_ctr(s);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->denied_req);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.denied_req);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->denied_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->denied_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->denied_req);
        stream_report_term_evt(s->scf, strm_tevt_type_intercepted);
        goto done_without_exp;
 
@@ -579,43 +579,43 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s
 
        s->logs.request_ts = now_ns;
        stream_inc_http_err_ctr(s);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->denied_req);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.denied_req);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->denied_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->denied_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->denied_req);
        stream_report_term_evt(s->scf, strm_tevt_type_intercepted);
        goto return_prx_err;
 
  return_fail_rewrite:
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_PRXCOND;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_rewrites);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_rewrites);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_rewrites);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_rewrites);
        /* fall through */
 
  return_int_err:
        txn->status = 500;
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->internal_errors);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->internal_errors);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->internal_errors);
        stream_report_term_evt(s->scf, strm_tevt_type_internal_err);
        goto return_prx_err;
 
  return_bad_req:
        txn->status = 400;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_req);
        stream_report_term_evt(s->scf, strm_tevt_type_proto_err);
        /* fall through */
 
@@ -748,24 +748,24 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit)
  return_fail_rewrite:
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_PRXCOND;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_rewrites);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_rewrites);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_rewrites);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_rewrites);
        /* fall through */
 
  return_int_err:
        txn->status = 500;
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->internal_errors);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->internal_errors);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->internal_errors);
        stream_report_term_evt(s->scf, strm_tevt_type_internal_err);
 
        http_set_term_flags(s);
@@ -871,19 +871,19 @@ int http_wait_for_request_body(struct stream *s, struct channel *req, int an_bit
        txn->status = 500;
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->internal_errors);
        if (s->flags & SF_BE_ASSIGNED)
-               _HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
+               _HA_ATOMIC_INC(&s->be->be_counters.shared->internal_errors);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->internal_errors);
        stream_report_term_evt(s->scf, strm_tevt_type_internal_err);
        goto return_prx_err;
 
  return_bad_req: /* let's centralize all bad requests */
        txn->status = 400;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_req);
        stream_report_term_evt(s->scf, strm_tevt_type_proto_err);
        /* fall through */
 
@@ -1100,24 +1100,24 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
        return 0;
 
   return_cli_abort:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
-       _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->cli_aborts);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->cli_aborts);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->cli_aborts);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->cli_aborts);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.cli_aborts);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->cli_aborts);
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= ((req->flags & CF_READ_TIMEOUT) ? SF_ERR_CLITO : SF_ERR_CLICL);
        status = 400;
        goto return_prx_cond;
 
   return_srv_abort:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.srv_aborts);
-       _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->srv_aborts);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->srv_aborts);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->srv_aborts);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->srv_aborts);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.srv_aborts);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->srv_aborts);
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= ((req->flags & CF_WRITE_TIMEOUT) ? SF_ERR_SRVTO : SF_ERR_SRVCL);
        status = 502;
@@ -1126,20 +1126,20 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
   return_int_err:
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
-       _HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->internal_errors);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->internal_errors);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->internal_errors);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.internal_errors);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->internal_errors);
        stream_report_term_evt(s->scf, strm_tevt_type_internal_err);
        status = 500;
        goto return_prx_cond;
 
   return_bad_req:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_req);
        stream_report_term_evt(s->scf, strm_tevt_type_proto_err);
        status = 400;
        /* fall through */
@@ -1173,9 +1173,9 @@ static __inline int do_l7_retry(struct stream *s, struct stconn *sc)
                        s->flags &= ~SF_CURR_SESS;
                        _HA_ATOMIC_DEC(&__objt_server(s->target)->cur_sess);
                }
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.retries);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->retries);
        }
-       _HA_ATOMIC_INC(&s->be->be_counters.retries);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->retries);
 
        req = &s->req;
        res = &s->res;
@@ -1292,9 +1292,9 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                        if (s->flags & SF_SRV_REUSED)
                                goto abort_keep_alive;
 
-                       _HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
+                       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_resp);
                        if (objt_server(s->target))
-                               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
+                               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_resp);
 
                        /* if the server refused the early data, just send a 425 */
                        if (conn && conn->err_code == CO_ER_SSL_EARLY_FAILED)
@@ -1329,9 +1329,9 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                                        return 0;
                                }
                        }
-                       _HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
+                       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_resp);
                        if (objt_server(s->target))
-                               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
+                               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_resp);
 
                        txn->status = 504;
                        stream_inc_http_fail_ctr(s);
@@ -1350,12 +1350,12 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                /* 3: client abort with an abortonclose */
                else if ((s->scb->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) && (s->scb->flags & SC_FL_SHUT_DONE) &&
                         (s->scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE))) {
-                       _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
-                       _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
+                       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->cli_aborts);
+                       _HA_ATOMIC_INC(&s->be->be_counters.shared->cli_aborts);
                        if (sess->listener && sess->listener->counters)
-                               _HA_ATOMIC_INC(&sess->listener->counters->cli_aborts);
+                               _HA_ATOMIC_INC(&sess->listener->counters->shared->cli_aborts);
                        if (objt_server(s->target))
-                               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.cli_aborts);
+                               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->cli_aborts);
 
                        txn->status = 400;
 
@@ -1388,9 +1388,9 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                        if (s->flags & SF_SRV_REUSED)
                                goto abort_keep_alive;
 
-                       _HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
+                       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_resp);
                        if (objt_server(s->target))
-                               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
+                               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_resp);
 
                        txn->status = 502;
                        stream_inc_http_fail_ctr(s);
@@ -1411,9 +1411,9 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                        if (s->flags & SF_SRV_REUSED)
                                goto abort_keep_alive;
 
-                       _HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
+                       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_resp);
                        if (objt_server(s->target))
-                               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
+                               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_resp);
                        rep->analysers &= AN_RES_FLT_END;
 
                        if (!(s->flags & SF_ERR_MASK))
@@ -1517,8 +1517,8 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                if (n < 1 || n > 5)
                        n = 0;
 
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.p.http.rsp[n]);
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.p.http.cum_req);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->p.http.rsp[n]);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->p.http.cum_req);
        }
 
        /*
@@ -1662,12 +1662,12 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
        return 1;
 
  return_int_err:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
-       _HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->internal_errors);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->internal_errors);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->internal_errors);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.internal_errors);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->internal_errors);
        txn->status = 500;
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
@@ -1683,9 +1683,9 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                return 0;
        }
 
-       _HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_resp);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_resp);
 
        txn->status = 502;
        stream_inc_http_fail_ctr(s);
@@ -1982,36 +1982,36 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s
        return 1;
 
  deny:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_resp);
-       _HA_ATOMIC_INC(&s->be->be_counters.denied_resp);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->denied_resp);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->denied_resp);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->denied_resp);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->denied_resp);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.denied_resp);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->denied_resp);
        stream_report_term_evt(s->scb, strm_tevt_type_intercepted);
        goto return_prx_err;
 
  return_fail_rewrite:
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_PRXCOND;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
-       _HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_rewrites);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_rewrites);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_rewrites);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_rewrites);
        /* fall through */
 
  return_int_err:
        txn->status = 500;
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
-       _HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->internal_errors);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->internal_errors);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->internal_errors);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.internal_errors);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->internal_errors);
        stream_report_term_evt(s->scb, strm_tevt_type_internal_err);
        goto return_prx_err;
 
@@ -2019,9 +2019,9 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s
        s->logs.t_data = -1; /* was not a valid response */
        txn->status = 502;
        stream_inc_http_fail_ctr(s);
-       _HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_resp);
        if (objt_server(s->target)) {
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_resp);
                health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_RSP);
        }
        stream_report_term_evt(s->scb, strm_tevt_type_proto_err);
@@ -2251,44 +2251,44 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
        return 0;
 
   return_srv_abort:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.srv_aborts);
-       _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->srv_aborts);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->srv_aborts);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->srv_aborts);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->srv_aborts);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.srv_aborts);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->srv_aborts);
        stream_inc_http_fail_ctr(s);
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= ((res->flags & CF_READ_TIMEOUT) ? SF_ERR_SRVTO : SF_ERR_SRVCL);
        goto return_error;
 
   return_cli_abort:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
-       _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->cli_aborts);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->cli_aborts);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->cli_aborts);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->cli_aborts);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.cli_aborts);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->cli_aborts);
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= ((res->flags & CF_WRITE_TIMEOUT) ? SF_ERR_CLITO : SF_ERR_CLICL);
        goto return_error;
 
   return_int_err:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
-       _HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->internal_errors);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->internal_errors);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->internal_errors);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.internal_errors);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->internal_errors);
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
        stream_report_term_evt(s->scb, strm_tevt_type_internal_err);
        goto return_error;
 
   return_bad_res:
-       _HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_resp);
        if (objt_server(s->target)) {
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_resp);
                health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_RSP);
        }
        stream_inc_http_fail_ctr(s);
@@ -2571,7 +2571,7 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc
                req->analysers &= AN_REQ_FLT_END;
 
                if (s->sess->fe == s->be) /* report it if the request was intercepted by the frontend */
-                       _HA_ATOMIC_INC(&s->sess->fe->fe_counters.intercepted_req);
+                       _HA_ATOMIC_INC(&s->sess->fe->fe_counters.shared->intercepted_req);
        }
 
   out:
@@ -4282,9 +4282,9 @@ enum rule_result http_wait_for_msg_body(struct stream *s, struct channel *chn,
        txn->status = 408;
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_CLITO;
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_req);
        goto abort;
 
   abort_res:
index a72251013323b5fd804fe86f5d350e51888b6a93..7b76decdb96c0a3f30d0f0e2e70e1486d8f3c75b 100644 (file)
@@ -1089,11 +1089,11 @@ void listener_accept(struct listener *l)
        }
 #endif
        if (p && p->fe_sps_lim) {
-               int max = freq_ctr_remain(&p->fe_counters.sess_per_sec, p->fe_sps_lim, 0);
+               int max = freq_ctr_remain(&p->fe_counters.shared->sess_per_sec, p->fe_sps_lim, 0);
 
                if (unlikely(!max)) {
                        /* frontend accept rate limit was reached */
-                       expire = tick_add(now_ms, next_event_delay(&p->fe_counters.sess_per_sec, p->fe_sps_lim, 0));
+                       expire = tick_add(now_ms, next_event_delay(&p->fe_counters.shared->sess_per_sec, p->fe_sps_lim, 0));
                        goto limit_proxy;
                }
 
@@ -1573,7 +1573,7 @@ void listener_accept(struct listener *l)
                dequeue_all_listeners();
 
                if (p && !MT_LIST_ISEMPTY(&p->listener_queue) &&
-                   (!p->fe_sps_lim || freq_ctr_remain(&p->fe_counters.sess_per_sec, p->fe_sps_lim, 0) > 0))
+                   (!p->fe_sps_lim || freq_ctr_remain(&p->fe_counters.shared->sess_per_sec, p->fe_sps_lim, 0) > 0))
                        dequeue_proxy_listeners(p, 0);
        }
        return;
@@ -1632,14 +1632,14 @@ void listener_release(struct listener *l)
        dequeue_all_listeners();
 
        if (fe && !MT_LIST_ISEMPTY(&fe->listener_queue) &&
-           (!fe->fe_sps_lim || freq_ctr_remain(&fe->fe_counters.sess_per_sec, fe->fe_sps_lim, 0) > 0))
+           (!fe->fe_sps_lim || freq_ctr_remain(&fe->fe_counters.shared->sess_per_sec, fe->fe_sps_lim, 0) > 0))
                dequeue_proxy_listeners(fe, 0);
        else if (fe) {
                unsigned int wait;
                int expire = TICK_ETERNITY;
 
                if (fe->task && fe->fe_sps_lim &&
-                   (wait = next_event_delay(&fe->fe_counters.sess_per_sec,fe->fe_sps_lim, 0))) {
+                   (wait = next_event_delay(&fe->fe_counters.shared->sess_per_sec,fe->fe_sps_lim, 0))) {
                        /* we're blocking because a limit was reached on the number of
                         * requests/s on the frontend. We want to re-check ASAP, which
                         * means in 1 ms before estimated expiration date, because the
index 12c8a3a4c9f65be7a93dd98bede7c1083387f3f8..046cd7425ce7f9202fd5c76d308c5162c0e75ff9 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -5946,15 +5946,15 @@ missing_budget:
 
 parse_error:
        if (l->counters)
-               _HA_ATOMIC_INC(&l->counters->failed_req);
-       _HA_ATOMIC_INC(&frontend->fe_counters.failed_req);
+               _HA_ATOMIC_INC(&l->counters->shared->failed_req);
+       _HA_ATOMIC_INC(&frontend->fe_counters.shared->failed_req);
 
        goto error;
 
 cli_abort:
        if (l->counters)
-               _HA_ATOMIC_INC(&l->counters->cli_aborts);
-       _HA_ATOMIC_INC(&frontend->fe_counters.cli_aborts);
+               _HA_ATOMIC_INC(&l->counters->shared->cli_aborts);
+       _HA_ATOMIC_INC(&frontend->fe_counters.shared->cli_aborts);
 
 error:
        se_fl_set(appctx->sedesc, SE_FL_ERROR);
index d65775509495e19941a46d6e3329b923271d0711..2264746980c9b4f5dd989cbaf1bd9b720af14c6b 100644 (file)
@@ -3729,10 +3729,10 @@ static int h1_handle_internal_err(struct h1c *h1c)
        }
        session_inc_http_req_ctr(sess);
        proxy_inc_fe_req_ctr(sess->listener, sess->fe, 1);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.p.http.rsp[5]);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->p.http.rsp[5]);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->internal_errors);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->internal_errors);
 
        h1c->errcode = 500;
        ret = h1_send_error(h1c);
@@ -3765,10 +3765,10 @@ static int h1_handle_parsing_error(struct h1c *h1c)
        session_inc_http_req_ctr(sess);
        session_inc_http_err_ctr(sess);
        proxy_inc_fe_req_ctr(sess->listener, sess->fe, 1);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.p.http.rsp[4]);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->p.http.rsp[4]);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_req);
 
        if (!h1c->errcode)
                h1c->errcode = 400;
@@ -3802,10 +3802,10 @@ static int h1_handle_not_impl_err(struct h1c *h1c)
 
        session_inc_http_req_ctr(sess);
        proxy_inc_fe_req_ctr(sess->listener, sess->fe, 1);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.p.http.rsp[4]);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->p.http.rsp[4]);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_req);
 
        h1c->errcode = 501;
        ret = h1_send_error(h1c);
@@ -3837,10 +3837,10 @@ static int h1_handle_req_tout(struct h1c *h1c)
 
        session_inc_http_req_ctr(sess);
        proxy_inc_fe_req_ctr(sess->listener, sess->fe, 1);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.p.http.rsp[4]);
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->p.http.rsp[4]);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_req);
 
        h1c->errcode = 408;
        ret = h1_send_error(h1c);
index 70f19bcbf93a160b44154c853b16450f27bd6fe7..b39f31621324e673b87e9e6703ded632cf4e0a03 100644 (file)
@@ -221,6 +221,8 @@ static inline void proxy_free_common(struct proxy *px)
        ha_free(&px->id);
        LIST_DEL_INIT(&px->global_list);
        drop_file_name(&px->conf.file);
+       ha_free(&px->fe_counters.shared);
+       ha_free(&px->be_counters.shared);
        ha_free(&px->check_command);
        ha_free(&px->check_path);
        ha_free(&px->cookie_name);
@@ -395,7 +397,10 @@ void deinit_proxy(struct proxy *p)
                free(l->name);
                free(l->label);
                free(l->per_thr);
-               free(l->counters);
+               if (l->counters) {
+                       free(l->counters->shared);
+                       free(l->counters);
+               }
                task_destroy(l->rx.rhttp.task);
 
                EXTRA_COUNTERS_FREE(l->extra_counters);
@@ -1710,16 +1715,39 @@ int setup_new_proxy(struct proxy *px, const char *name, unsigned int cap, char *
        init_new_proxy(px);
 
        last_change = ns_to_sec(now_ns);
-       if (cap & PR_CAP_FE)
-               px->fe_counters.last_change = last_change;
-       if (cap & PR_CAP_BE)
-               px->be_counters.last_change = last_change;
+       /* allocate private memory for shared counters: used as a fallback
+        * or when sharing is disabled. If sharing is enabled pointers will
+        * be updated to point to the proper shared memory location during
+        * proxy postparsing, see proxy_postparse()
+        */
+       if (cap & PR_CAP_FE) {
+               px->fe_counters.shared = calloc(1, sizeof(*px->fe_counters.shared));
+               if (!px->fe_counters.shared) {
+                       memprintf(errmsg, "out of memory");
+                       goto fail;
+               }
+               HA_ATOMIC_STORE(&px->fe_counters.shared->last_change, last_change);
+       }
+       if (cap & (PR_CAP_FE|PR_CAP_BE)) {
+               /* by default stream->be points to stream->fe, thus proxy
+                * be_counters may be used even if the proxy lacks the backend
+                * capability
+                */
+               px->be_counters.shared = calloc(1, sizeof(*px->be_counters.shared));
+               if (!px->be_counters.shared) {
+                       memprintf(errmsg, "out of memory");
+                       goto fail;
+               }
+
+               HA_ATOMIC_STORE(&px->be_counters.shared->last_change, last_change);
+       }
+
 
        if (name) {
                px->id = strdup(name);
                if (!px->id) {
-                       memprintf(errmsg, "proxy '%s': out of memory", name);
-                       return 0;
+                       memprintf(errmsg, "out of memory");
+                       goto fail;
                }
        }
 
@@ -1732,6 +1760,16 @@ int setup_new_proxy(struct proxy *px, const char *name, unsigned int cap, char *
                LIST_APPEND(&proxies, &px->global_list);
 
        return 1;
+
+ fail:
+       if (name)
+               memprintf(errmsg, "proxy '%s': %s", name, *errmsg);
+
+       ha_free(&px->id);
+       ha_free(&px->fe_counters.shared);
+       ha_free(&px->be_counters.shared);
+
+       return 0;
 }
 
 /* Allocates a new proxy <name> of type <cap>.
@@ -2082,9 +2120,9 @@ void proxy_cond_disable(struct proxy *p)
         * the data plane but on the control plane.
         */
        if (p->cap & PR_CAP_FE)
-               cum_conn = p->fe_counters.cum_conn;
+               cum_conn = HA_ATOMIC_LOAD(&p->fe_counters.shared->cum_conn);
        if (p->cap & PR_CAP_BE)
-               cum_sess = p->be_counters.cum_sess;
+               cum_sess = HA_ATOMIC_LOAD(&p->be_counters.shared->cum_sess);
 
        if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP || p->mode == PR_MODE_SYSLOG || p->mode == PR_MODE_SPOP) && !(p->cap & PR_CAP_INT))
                ha_warning("Proxy %s stopped (cumulated conns: FE: %lld, BE: %lld).\n",
@@ -2179,7 +2217,7 @@ struct task *manage_proxy(struct task *t, void *context, unsigned int state)
                goto out;
 
        if (p->fe_sps_lim &&
-           (wait = next_event_delay(&p->fe_counters.sess_per_sec, p->fe_sps_lim, 0))) {
+           (wait = next_event_delay(&p->fe_counters.shared->sess_per_sec, p->fe_sps_lim, 0))) {
                /* we're blocking because a limit was reached on the number of
                 * requests/s on the frontend. We want to re-check ASAP, which
                 * means in 1 ms before estimated expiration date, because the
@@ -2923,7 +2961,7 @@ static int dump_servers_state(struct appctx *appctx)
                dump_server_addr(&srv->check.addr, srv_check_addr);
                dump_server_addr(&srv->agent.addr, srv_agent_addr);
 
-               srv_time_since_last_change = ns_to_sec(now_ns) - srv->counters.last_change;
+               srv_time_since_last_change = ns_to_sec(now_ns) - HA_ATOMIC_LOAD(&srv->counters.shared->last_change);
                bk_f_forced_id = px->options & PR_O_FORCED_ID ? 1 : 0;
                srv_f_forced_id = srv->flags & SRV_F_FORCED_ID ? 1 : 0;
 
index 1f9f6d8ababe5797a497acc0a7d645dcf3e4b684..8d517f7e767f1f82634e99a321360a91c98c19c8 100644 (file)
@@ -103,6 +103,7 @@ DECLARE_POOL(pool_head_pendconn, "pendconn", sizeof(struct pendconn));
 unsigned int srv_dynamic_maxconn(const struct server *s)
 {
        unsigned int max;
+       unsigned long last_change;
 
        if (s->proxy->beconn >= s->proxy->fullconn)
                /* no fullconn or proxy is full */
@@ -113,11 +114,13 @@ unsigned int srv_dynamic_maxconn(const struct server *s)
        else max = MAX(s->minconn,
                       s->proxy->beconn * s->maxconn / s->proxy->fullconn);
 
+       last_change = HA_ATOMIC_LOAD(&s->counters.shared->last_change);
+
        if ((s->cur_state == SRV_ST_STARTING) &&
-           ns_to_sec(now_ns) < s->counters.last_change + s->slowstart &&
-           ns_to_sec(now_ns) >= s->counters.last_change) {
+           ns_to_sec(now_ns) < last_change + s->slowstart &&
+           ns_to_sec(now_ns) >= last_change) {
                unsigned int ratio;
-               ratio = 100 * (ns_to_sec(now_ns) - s->counters.last_change) / s->slowstart;
+               ratio = 100 * (ns_to_sec(now_ns) - last_change) / s->slowstart;
                max = MAX(1, max * ratio / 100);
        }
        return max;
index aae4cfa78cd534e9a70505796af87711cd6753ce..758d7e2a7d253f360cf33574784f6a6662bec993 100644 (file)
@@ -142,10 +142,12 @@ const char *srv_op_st_chg_cause(enum srv_op_st_chg_cause cause)
 
 int srv_downtime(const struct server *s)
 {
-       if ((s->cur_state != SRV_ST_STOPPED) || s->counters.last_change >= ns_to_sec(now_ns))           // ignore negative time
+       unsigned long last_change = HA_ATOMIC_LOAD(&s->counters.shared->last_change);
+
+       if ((s->cur_state != SRV_ST_STOPPED) || last_change >= ns_to_sec(now_ns))               // ignore negative time
                return s->down_time;
 
-       return ns_to_sec(now_ns) - s->counters.last_change + s->down_time;
+       return ns_to_sec(now_ns) - last_change + s->down_time;
 }
 
 int srv_getinter(const struct check *check)
@@ -2456,10 +2458,11 @@ INITCALL1(STG_REGISTER, srv_register_keywords, &srv_kws);
  */
 void server_recalc_eweight(struct server *sv, int must_update)
 {
+       unsigned long last_change = HA_ATOMIC_LOAD(&sv->counters.shared->last_change);
        struct proxy *px = sv->proxy;
        unsigned w;
 
-       if (ns_to_sec(now_ns) < sv->counters.last_change || ns_to_sec(now_ns) >= sv->counters.last_change + sv->slowstart) {
+       if (ns_to_sec(now_ns) < last_change || ns_to_sec(now_ns) >= last_change + sv->slowstart) {
                /* go to full throttle if the slowstart interval is reached unless server is currently down */
                if ((sv->cur_state != SRV_ST_STOPPED) && (sv->next_state == SRV_ST_STARTING))
                        sv->next_state = SRV_ST_RUNNING;
@@ -2471,7 +2474,7 @@ void server_recalc_eweight(struct server *sv, int must_update)
        if ((sv->cur_state == SRV_ST_STOPPED) && (sv->next_state == SRV_ST_STARTING) && (px->lbprm.algo & BE_LB_PROP_DYN))
                w = 1;
        else if ((sv->next_state == SRV_ST_STARTING) && (px->lbprm.algo & BE_LB_PROP_DYN))
-               w = (px->lbprm.wdiv * (ns_to_sec(now_ns) - sv->counters.last_change) + sv->slowstart) / sv->slowstart;
+               w = (px->lbprm.wdiv * (ns_to_sec(now_ns) - last_change) + sv->slowstart) / sv->slowstart;
        else
                w = px->lbprm.wdiv;
 
@@ -3025,11 +3028,18 @@ void srv_settings_cpy(struct server *srv, const struct server *src, int srv_tmpl
 struct server *new_server(struct proxy *proxy)
 {
        struct server *srv;
+       struct be_counters_shared *scounters;
 
        srv = calloc(1, sizeof *srv);
        if (!srv)
                return NULL;
 
+       scounters = calloc(1, sizeof(*scounters));
+       if (!scounters) {
+               ha_free(&srv);
+               return NULL;
+       }
+
        srv_take(srv);
 
        srv->obj_type = OBJ_TYPE_SERVER;
@@ -3042,7 +3052,8 @@ struct server *new_server(struct proxy *proxy)
        srv->rid = 0; /* rid defaults to 0 */
 
        srv->next_state = SRV_ST_RUNNING; /* early server setup */
-       srv->counters.last_change = ns_to_sec(now_ns);
+       srv->counters.shared = scounters;
+       HA_ATOMIC_STORE(&srv->counters.shared->last_change, ns_to_sec(now_ns));
 
        srv->check.obj_type = OBJ_TYPE_CHECK;
        srv->check.status = HCHK_STATUS_INI;
@@ -3114,6 +3125,7 @@ void srv_free_params(struct server *srv)
        free(srv->resolvers_id);
        free(srv->addr_node.key);
        free(srv->lb_nodes);
+       free(srv->counters.shared);
        if (srv->log_target) {
                deinit_log_target(srv->log_target);
                free(srv->log_target);
@@ -5790,7 +5802,7 @@ static int init_srv_slowstart(struct server *srv)
                if (srv->next_state == SRV_ST_STARTING) {
                        task_schedule(srv->warmup,
                                      tick_add(now_ms,
-                                              MS_TO_TICKS(MAX(1000, (ns_to_sec(now_ns) - srv->counters.last_change)) / 20)));
+                                              MS_TO_TICKS(MAX(1000, (ns_to_sec(now_ns) - HA_ATOMIC_LOAD(&srv->counters.shared->last_change))) / 20)));
                }
        }
 
@@ -6993,14 +7005,16 @@ static void srv_update_status(struct server *s, int type, int cause)
        /* check if server stats must be updated due the the server state change */
        if (srv_prev_state != s->cur_state) {
                if (srv_prev_state == SRV_ST_STOPPED) {
+                       unsigned long last_change = HA_ATOMIC_LOAD(&s->counters.shared->last_change);
+
                        /* server was down and no longer is */
-                       if (s->counters.last_change < ns_to_sec(now_ns))                        // ignore negative times
-                               s->down_time += ns_to_sec(now_ns) - s->counters.last_change;
+                       if (last_change < ns_to_sec(now_ns))                        // ignore negative times
+                               s->down_time += ns_to_sec(now_ns) - last_change;
                        _srv_event_hdl_publish(EVENT_HDL_SUB_SERVER_UP, cb_data.common, s);
                }
                else if (s->cur_state == SRV_ST_STOPPED) {
                        /* server was up and is currently down */
-                       s->counters.down_trans++;
+                       HA_ATOMIC_INC(&s->counters.shared->down_trans);
                        _srv_event_hdl_publish(EVENT_HDL_SUB_SERVER_DOWN, cb_data.common, s);
                }
 
@@ -7011,7 +7025,7 @@ static void srv_update_status(struct server *s, int type, int cause)
                if (s->cur_state != SRV_ST_RUNNING && s->proxy->ready_srv == s)
                        HA_ATOMIC_STORE(&s->proxy->ready_srv, NULL);
 
-               s->counters.last_change = ns_to_sec(now_ns);
+               HA_ATOMIC_STORE(&s->counters.shared->last_change, ns_to_sec(now_ns));
 
                /* publish the state change */
                _srv_event_hdl_prepare_state(&cb_data.state,
@@ -7023,12 +7037,14 @@ static void srv_update_status(struct server *s, int type, int cause)
        if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
                set_backend_down(s->proxy); /* backend going down */
        else if (!prev_srv_count && (s->proxy->srv_bck || s->proxy->srv_act)) {
+               unsigned long last_change = HA_ATOMIC_LOAD(&s->proxy->be_counters.shared->last_change);
+
                /* backend was down and is back up again:
                 * no helper function, updating last_change and backend downtime stats
                 */
-               if (s->proxy->be_counters.last_change < ns_to_sec(now_ns))         // ignore negative times
-                       s->proxy->down_time += ns_to_sec(now_ns) - s->proxy->be_counters.last_change;
-               s->proxy->be_counters.last_change = ns_to_sec(now_ns);
+               if (last_change < ns_to_sec(now_ns))         // ignore negative times
+                       s->proxy->down_time += ns_to_sec(now_ns) - last_change;
+               HA_ATOMIC_STORE(&s->proxy->be_counters.shared->last_change, ns_to_sec(now_ns));
        }
 }
 
index df6c32bd238760d40fbfafd6877ef70cc88c3f00..6f3718a415d27d13e61bbc625a065c823b49c92a 100644 (file)
@@ -321,7 +321,7 @@ static void srv_state_srv_update(struct server *srv, int version, char **params)
                        srv_adm_set_drain(srv);
        }
 
-       srv->counters.last_change = ns_to_sec(now_ns) - srv_last_time_change;
+       HA_ATOMIC_STORE(&srv->counters.shared->last_change, ns_to_sec(now_ns) - srv_last_time_change);
        srv->check.status = srv_check_status;
        srv->check.result = srv_check_result;
 
index ae8e40fef1146084c0b5ee47e554dc309dd03bfb..28515fdb312688b379a4dc3c5bc60b6638eba50b 100644 (file)
@@ -258,7 +258,7 @@ static int parse_stat_line(struct ist line,
        struct server *srv;
        struct proxy *px;
        struct ist token;
-       char *base_off;
+       char *base_off, *base_off_shared;
        char *guid;
        int i, off;
 
@@ -280,13 +280,19 @@ static int parse_stat_line(struct ist line,
                if (domain == STFILE_DOMAIN_PX_FE) {
                        if (!(px->cap & PR_CAP_FE))
                                return 0; /* silently ignored fe/be mismatch */
+
+                       base_off_shared = (char *)px->fe_counters.shared;
                        base_off = (char *)&px->fe_counters;
+
                        off = 0;
                }
                else if (domain == STFILE_DOMAIN_PX_BE) {
                        if (!(px->cap & PR_CAP_BE))
                                return 0; /* silently ignored fe/be mismatch */
+
+                       base_off_shared = (char *)px->be_counters.shared;
                        base_off = (char *)&px->be_counters;
+
                        off = 1;
                }
                else {
@@ -304,7 +310,9 @@ static int parse_stat_line(struct ist line,
                if (!li->counters)
                        return 0;
 
+               base_off_shared = (char *)li->counters->shared;
                base_off = (char *)li->counters;
+
                off = 0;
                break;
 
@@ -313,7 +321,9 @@ static int parse_stat_line(struct ist line,
                        goto err;
 
                srv = __objt_server(node->obj_type);
+               base_off_shared = (char *)srv->counters.shared;
                base_off = (char *)&srv->counters;
+
                off = 1;
                break;
 
@@ -332,7 +342,10 @@ static int parse_stat_line(struct ist line,
                if (!col)
                        continue;
 
-               load_ctr(col, token, base_off + col->metric.offset[off]);
+               if (col->flags & STAT_COL_FL_SHARED)
+                       load_ctr(col, token, base_off_shared + col->metric.offset[off]);
+               else
+                       load_ctr(col, token, base_off + col->metric.offset[off]);
        }
 
        return 0;
index 1ea3114ff5396d9f2c9d1f9cb97a91aa8829f100..2cf6bf005ce84f027f743525ae9666e5175f637e 100644 (file)
     .metric.offset[1] = offsetof(struct be_counters, offset_f),                \
   }
 
+/* Define a new generic shared metric for both frontend and backend sides. */
+#define ME_NEW_PX_SHARED(name_f, alt_n, nature, format, offset_f, cap_f, desc_f)\
+  {                                                                            \
+    ME_NEW_COMMON(name_f, alt_n, nature, format, offset_f, cap_f, desc_f)      \
+    .flags = STAT_COL_FL_GENERIC | STAT_COL_FL_SHARED,                         \
+    .metric.offset[0] = offsetof(struct fe_counters_shared, offset_f),         \
+    .metric.offset[1] = offsetof(struct be_counters_shared, offset_f),         \
+  }
+
 /* Define a new generic metric for frontend side only. */
 #define ME_NEW_FE(name_f, alt_n, nature, format, offset_f, cap_f, desc_f)     \
   {                                                                           \
     .metric.offset[0] = offsetof(struct fe_counters, offset_f),               \
   }
 
+/* Define a new generic shared metric for frontend side only. */
+#define ME_NEW_FE_SHARED(name_f, alt_n, nature, format, offset_f, cap_f, desc_f)\
+  {                                                                           \
+    ME_NEW_COMMON(name_f, alt_n, nature, format, offset_f, cap_f, desc_f)     \
+    .flags = STAT_COL_FL_GENERIC | STAT_COL_FL_SHARED,                        \
+    .metric.offset[0] = offsetof(struct fe_counters_shared, offset_f),        \
+  }
+
 /* Define a new generic metric for backend side only. */
 #define ME_NEW_BE(name_f, alt_n, nature, format, offset_f, cap_f, desc_f)     \
   {                                                                           \
     .metric.offset[1] = offsetof(struct be_counters, offset_f),               \
   }
 
+/* Define a new generic shared metric for backend side only. */
+#define ME_NEW_BE_SHARED(name_f, alt_n, nature, format, offset_f, cap_f, desc_f)\
+  {                                                                           \
+    ME_NEW_COMMON(name_f, alt_n, nature, format, offset_f, cap_f, desc_f)     \
+    .flags = STAT_COL_FL_GENERIC | STAT_COL_FL_SHARED,                        \
+    .metric.offset[1] = offsetof(struct be_counters_shared, offset_f),        \
+  }
+
 const struct stat_col stat_cols_px[ST_I_PX_MAX] = {
        [ST_I_PX_PXNAME]                        = { .name = "pxname",                      .alt_name = NULL,                              .desc = "Proxy name" },
        [ST_I_PX_SVNAME]                        = { .name = "svname",                      .alt_name = NULL,                              .desc = "Server name" },
@@ -58,56 +83,56 @@ const struct stat_col stat_cols_px[ST_I_PX_MAX] = {
        [ST_I_PX_SCUR]                          = { .name = "scur",                        .alt_name = "current_sessions",                .desc = "Number of current sessions on the frontend, backend or server", .cap = STATS_PX_CAP_LFBS},
        [ST_I_PX_SMAX]                          = { .name = "smax",                        .alt_name = "max_sessions",                    .desc = "Highest value of current sessions encountered since process started", .cap = STATS_PX_CAP_LFBS },
        [ST_I_PX_SLIM]                          = { .name = "slim",                        .alt_name = "limit_sessions",                  .desc = "Frontend/listener/server's maxconn, backend's fullconn", .cap = STATS_PX_CAP_LFBS },
-       [ST_I_PX_STOT]          = ME_NEW_PX("stot",          "sessions_total",                     FN_COUNTER, FF_U64, cum_sess,               STATS_PX_CAP_LFBS, "Total number of sessions since process started"),
-       [ST_I_PX_BIN]           = ME_NEW_PX("bin",           "bytes_in_total",                     FN_COUNTER, FF_U64, bytes_in,               STATS_PX_CAP_LFBS, "Total number of request bytes since process started"),
-       [ST_I_PX_BOUT]          = ME_NEW_PX("bout",          "bytes_out_total",                    FN_COUNTER, FF_U64, bytes_out,              STATS_PX_CAP_LFBS, "Total number of response bytes since process started"),
-       [ST_I_PX_DREQ]          = ME_NEW_PX("dreq",          "requests_denied_total",              FN_COUNTER, FF_U64, denied_req,             STATS_PX_CAP_LFB_, "Total number of denied requests since process started"),
-       [ST_I_PX_DRESP]         = ME_NEW_PX("dresp",         "responses_denied_total",             FN_COUNTER, FF_U64, denied_resp,            STATS_PX_CAP_LFBS, "Total number of denied responses since process started"),
-       [ST_I_PX_EREQ]          = ME_NEW_FE("ereq",          "request_errors_total",               FN_COUNTER, FF_U64, failed_req,             STATS_PX_CAP_LF__, "Total number of invalid requests since process started"),
-       [ST_I_PX_ECON]          = ME_NEW_BE("econ",          "connection_errors_total",            FN_COUNTER, FF_U64, failed_conns,           STATS_PX_CAP___BS, "Total number of failed connections to server since the worker process started"),
-       [ST_I_PX_ERESP]         = ME_NEW_BE("eresp",         "response_errors_total",              FN_COUNTER, FF_U64, failed_resp,            STATS_PX_CAP___BS, "Total number of invalid responses since the worker process started"),
-       [ST_I_PX_WRETR]         = ME_NEW_BE("wretr",         "retry_warnings_total",               FN_COUNTER, FF_U64, retries,                STATS_PX_CAP___BS, "Total number of server connection retries since the worker process started"),
-       [ST_I_PX_WREDIS]        = ME_NEW_BE("wredis",        "redispatch_warnings_total",          FN_COUNTER, FF_U64, redispatches,           STATS_PX_CAP___BS, "Total number of server redispatches due to connection failures since the worker process started"),
+       [ST_I_PX_STOT]          = ME_NEW_PX_SHARED("stot",          "sessions_total",                     FN_COUNTER, FF_U64, cum_sess,               STATS_PX_CAP_LFBS, "Total number of sessions since process started"),
+       [ST_I_PX_BIN]           = ME_NEW_PX_SHARED("bin",           "bytes_in_total",                     FN_COUNTER, FF_U64, bytes_in,               STATS_PX_CAP_LFBS, "Total number of request bytes since process started"),
+       [ST_I_PX_BOUT]          = ME_NEW_PX_SHARED("bout",          "bytes_out_total",                    FN_COUNTER, FF_U64, bytes_out,              STATS_PX_CAP_LFBS, "Total number of response bytes since process started"),
+       [ST_I_PX_DREQ]          = ME_NEW_PX_SHARED("dreq",          "requests_denied_total",              FN_COUNTER, FF_U64, denied_req,             STATS_PX_CAP_LFB_, "Total number of denied requests since process started"),
+       [ST_I_PX_DRESP]         = ME_NEW_PX_SHARED("dresp",         "responses_denied_total",             FN_COUNTER, FF_U64, denied_resp,            STATS_PX_CAP_LFBS, "Total number of denied responses since process started"),
+       [ST_I_PX_EREQ]          = ME_NEW_FE_SHARED("ereq",          "request_errors_total",               FN_COUNTER, FF_U64, failed_req,             STATS_PX_CAP_LF__, "Total number of invalid requests since process started"),
+       [ST_I_PX_ECON]          = ME_NEW_BE_SHARED("econ",          "connection_errors_total",            FN_COUNTER, FF_U64, failed_conns,           STATS_PX_CAP___BS, "Total number of failed connections to server since the worker process started"),
+       [ST_I_PX_ERESP]         = ME_NEW_BE_SHARED("eresp",         "response_errors_total",              FN_COUNTER, FF_U64, failed_resp,            STATS_PX_CAP___BS, "Total number of invalid responses since the worker process started"),
+       [ST_I_PX_WRETR]         = ME_NEW_BE_SHARED("wretr",         "retry_warnings_total",               FN_COUNTER, FF_U64, retries,                STATS_PX_CAP___BS, "Total number of server connection retries since the worker process started"),
+       [ST_I_PX_WREDIS]        = ME_NEW_BE_SHARED("wredis",        "redispatch_warnings_total",          FN_COUNTER, FF_U64, redispatches,           STATS_PX_CAP___BS, "Total number of server redispatches due to connection failures since the worker process started"),
        [ST_I_PX_STATUS]                        = { .name = "status",                      .alt_name = "status",                          .desc = "Frontend/listen status: OPEN/WAITING/FULL/STOP; backend: UP/DOWN; server: last check status", .cap = STATS_PX_CAP_LFBS },
        [ST_I_PX_WEIGHT]                        = { .name = "weight",                      .alt_name = "weight",                          .desc = "Server's effective weight, or sum of active servers' effective weights for a backend", .cap = STATS_PX_CAP___BS },
        [ST_I_PX_ACT]                           = { .name = "act",                         .alt_name = "active_servers",                  .desc = "Total number of active UP servers with a non-zero weight", .cap = STATS_PX_CAP___BS },
        [ST_I_PX_BCK]                           = { .name = "bck",                         .alt_name = "backup_servers",                  .desc = "Total number of backup UP servers with a non-zero weight", .cap = STATS_PX_CAP___BS },
-       [ST_I_PX_CHKFAIL]       = ME_NEW_BE("chkfail",       "check_failures_total",               FN_COUNTER, FF_U64, failed_checks,          STATS_PX_CAP____S, "Total number of failed individual health checks per server/backend, since the worker process started"),
-       [ST_I_PX_CHKDOWN]       = ME_NEW_BE("chkdown",       "check_up_down_total",                FN_COUNTER, FF_U64, down_trans,             STATS_PX_CAP___BS, "Total number of failed checks causing UP to DOWN server transitions, per server/backend, since the worker process started"),
-       [ST_I_PX_LASTCHG]       = ME_NEW_BE("lastchg",       "check_last_change_seconds",          FN_AGE,     FF_U32, last_change,            STATS_PX_CAP___BS, "How long ago the last server state changed, in seconds"),
+       [ST_I_PX_CHKFAIL]       = ME_NEW_BE_SHARED("chkfail",       "check_failures_total",               FN_COUNTER, FF_U64, failed_checks,          STATS_PX_CAP____S, "Total number of failed individual health checks per server/backend, since the worker process started"),
+       [ST_I_PX_CHKDOWN]       = ME_NEW_BE_SHARED("chkdown",       "check_up_down_total",                FN_COUNTER, FF_U64, down_trans,             STATS_PX_CAP___BS, "Total number of failed checks causing UP to DOWN server transitions, per server/backend, since the worker process started"),
+       [ST_I_PX_LASTCHG]       = ME_NEW_BE_SHARED("lastchg",       "check_last_change_seconds",          FN_AGE,     FF_U32, last_change,            STATS_PX_CAP___BS, "How long ago the last server state changed, in seconds"),
        [ST_I_PX_DOWNTIME]                      = { .name = "downtime",                    .alt_name = "downtime_seconds_total",          .desc = "Total time spent in DOWN state, for server or backend", .cap = STATS_PX_CAP___BS },
        [ST_I_PX_QLIMIT]                        = { .name = "qlimit",                      .alt_name = "queue_limit",                     .desc = "Limit on the number of connections in queue, for servers only (maxqueue argument)", .cap = STATS_PX_CAP____S },
        [ST_I_PX_PID]                           = { .name = "pid",                         .alt_name = NULL,                              .desc = "Relative worker process number (1)" },
        [ST_I_PX_IID]                           = { .name = "iid",                         .alt_name = NULL,                              .desc = "Frontend or Backend numeric identifier ('id' setting)" },
        [ST_I_PX_SID]                           = { .name = "sid",                         .alt_name = NULL,                              .desc = "Server numeric identifier ('id' setting)" },
        [ST_I_PX_THROTTLE]                      = { .name = "throttle",                    .alt_name = "current_throttle",                .desc = "Throttling ratio applied to a server's maxconn and weight during the slowstart period (0 to 100%)", .cap = STATS_PX_CAP____S },
-       [ST_I_PX_LBTOT]         = ME_NEW_BE("lbtot",         "loadbalanced_total",                 FN_COUNTER, FF_U64, cum_lbconn,             STATS_PX_CAP___BS, "Total number of requests routed by load balancing since the worker process started (ignores queue pop and stickiness)"),
+       [ST_I_PX_LBTOT]         = ME_NEW_BE_SHARED("lbtot",         "loadbalanced_total",                 FN_COUNTER, FF_U64, cum_lbconn,             STATS_PX_CAP___BS, "Total number of requests routed by load balancing since the worker process started (ignores queue pop and stickiness)"),
        [ST_I_PX_TRACKED]                       = { .name = "tracked",                     .alt_name = NULL,                              .desc = "Name of the other server this server tracks for its state" },
        [ST_I_PX_TYPE]                          = { .name = "type",                        .alt_name = NULL,                              .desc = "Type of the object (Listener, Frontend, Backend, Server)" },
-       [ST_I_PX_RATE]          = ME_NEW_PX("rate",          "current_session_rate",               FN_RATE,    FF_U32, sess_per_sec,           STATS_PX_CAP__FBS, "Total number of sessions processed by this object over the last second (sessions for listeners/frontends, requests for backends/servers)"),
+       [ST_I_PX_RATE]          = ME_NEW_PX_SHARED("rate",          "current_session_rate",               FN_RATE,    FF_U32, sess_per_sec,           STATS_PX_CAP__FBS, "Total number of sessions processed by this object over the last second (sessions for listeners/frontends, requests for backends/servers)"),
        [ST_I_PX_RATE_LIM]                      = { .name = "rate_lim",                    .alt_name = "limit_session_rate",              .desc = "Limit on the number of sessions accepted in a second (frontend only, 'rate-limit sessions' setting)", .cap = STATS_PX_CAP__F__ },
        [ST_I_PX_RATE_MAX]                      = { .name = "rate_max",                    .alt_name = "max_session_rate",                .desc = "Highest value of sessions per second observed since the worker process started", .cap = STATS_PX_CAP__FBS },
        [ST_I_PX_CHECK_STATUS]                  = { .name = "check_status",                .alt_name = "check_status",                    .desc = "Status report of the server's latest health check, prefixed with '*' if a check is currently in progress", .cap = STATS_PX_CAP____S },
        [ST_I_PX_CHECK_CODE]                    = { .name = "check_code",                  .alt_name = "check_code",                      .desc = "HTTP/SMTP/LDAP status code reported by the latest server health check", .cap = STATS_PX_CAP____S },
        [ST_I_PX_CHECK_DURATION]                = { .name = "check_duration",              .alt_name = "check_duration_seconds",          .desc = "Total duration of the latest server health check, in milliseconds", .cap = STATS_PX_CAP____S },
-       [ST_I_PX_HRSP_1XX]      = ME_NEW_PX("hrsp_1xx",      "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[1],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status 100-199 returned by this object since the worker process started"),
-       [ST_I_PX_HRSP_2XX]      = ME_NEW_PX("hrsp_2xx",      "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[2],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status 200-299 returned by this object since the worker process started"),
-       [ST_I_PX_HRSP_3XX]      = ME_NEW_PX("hrsp_3xx",      "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[3],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status 300-399 returned by this object since the worker process started"),
-       [ST_I_PX_HRSP_4XX]      = ME_NEW_PX("hrsp_4xx",      "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[4],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status 400-499 returned by this object since the worker process started"),
-       [ST_I_PX_HRSP_5XX]      = ME_NEW_PX("hrsp_5xx",      "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[5],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status 500-599 returned by this object since the worker process started"),
-       [ST_I_PX_HRSP_OTHER]    = ME_NEW_PX("hrsp_other",    "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[0],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status <100, >599 returned by this object since the worker process started (error -1 included)"),
-       [ST_I_PX_HANAFAIL]      = ME_NEW_BE("hanafail",      NULL,                                 FN_COUNTER, FF_U64, failed_hana,            STATS_PX_CAP____S, "Total number of failed checks caused by an 'on-error' directive after an 'observe' condition matched"),
-       [ST_I_PX_REQ_RATE]      = ME_NEW_FE("req_rate",      NULL,                                 FN_RATE,    FF_U32, req_per_sec,            STATS_PX_CAP__F__, "Number of HTTP requests processed over the last second on this object"),
+       [ST_I_PX_HRSP_1XX]      = ME_NEW_PX_SHARED("hrsp_1xx",      "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[1],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status 100-199 returned by this object since the worker process started"),
+       [ST_I_PX_HRSP_2XX]      = ME_NEW_PX_SHARED("hrsp_2xx",      "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[2],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status 200-299 returned by this object since the worker process started"),
+       [ST_I_PX_HRSP_3XX]      = ME_NEW_PX_SHARED("hrsp_3xx",      "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[3],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status 300-399 returned by this object since the worker process started"),
+       [ST_I_PX_HRSP_4XX]      = ME_NEW_PX_SHARED("hrsp_4xx",      "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[4],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status 400-499 returned by this object since the worker process started"),
+       [ST_I_PX_HRSP_5XX]      = ME_NEW_PX_SHARED("hrsp_5xx",      "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[5],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status 500-599 returned by this object since the worker process started"),
+       [ST_I_PX_HRSP_OTHER]    = ME_NEW_PX_SHARED("hrsp_other",    "http_responses_total",               FN_COUNTER, FF_U64, p.http.rsp[0],          STATS_PX_CAP__FBS, "Total number of HTTP responses with status <100, >599 returned by this object since the worker process started (error -1 included)"),
+       [ST_I_PX_HANAFAIL]      = ME_NEW_BE_SHARED("hanafail",      NULL,                                 FN_COUNTER, FF_U64, failed_hana,            STATS_PX_CAP____S, "Total number of failed checks caused by an 'on-error' directive after an 'observe' condition matched"),
+       [ST_I_PX_REQ_RATE]      = ME_NEW_FE_SHARED("req_rate",      NULL,                                 FN_RATE,    FF_U32, req_per_sec,            STATS_PX_CAP__F__, "Number of HTTP requests processed over the last second on this object"),
        [ST_I_PX_REQ_RATE_MAX]                  = { .name = "req_rate_max",                .alt_name = "http_requests_rate_max",          .desc = "Highest value of http requests observed since the worker process started", .cap = STATS_PX_CAP__F__ },
        /* Note: ST_I_PX_REQ_TOT is also displayed on frontend but does not uses a raw counter value, see me_generate_field() for details. */
-       [ST_I_PX_REQ_TOT]       = ME_NEW_BE("req_tot",       "http_requests_total",                FN_COUNTER, FF_U64, p.http.cum_req,         STATS_PX_CAP__FBS, "Total number of HTTP requests processed by this object since the worker process started"),
-       [ST_I_PX_CLI_ABRT]      = ME_NEW_BE("cli_abrt",      "client_aborts_total",                FN_COUNTER, FF_U64, cli_aborts,             STATS_PX_CAP___BS, "Total number of requests or connections aborted by the client since the worker process started"),
-       [ST_I_PX_SRV_ABRT]      = ME_NEW_BE("srv_abrt",      "server_aborts_total",                FN_COUNTER, FF_U64, srv_aborts,             STATS_PX_CAP___BS, "Total number of requests or connections aborted by the server since the worker process started"),
-       [ST_I_PX_COMP_IN]       = ME_NEW_PX("comp_in",       "http_comp_bytes_in_total",           FN_COUNTER, FF_U64, comp_in[COMP_DIR_RES],  STATS_PX_CAP__FB_, "Total number of bytes submitted to the HTTP compressor for this object since the worker process started"),
-       [ST_I_PX_COMP_OUT]      = ME_NEW_PX("comp_out",      "http_comp_bytes_out_total",          FN_COUNTER, FF_U64, comp_out[COMP_DIR_RES], STATS_PX_CAP__FB_, "Total number of bytes emitted by the HTTP compressor for this object since the worker process started"),
-       [ST_I_PX_COMP_BYP]      = ME_NEW_PX("comp_byp",      "http_comp_bytes_bypassed_total",     FN_COUNTER, FF_U64, comp_byp[COMP_DIR_RES], STATS_PX_CAP__FB_, "Total number of bytes that bypassed HTTP compression for this object since the worker process started (CPU/memory/bandwidth limitation)"),
-       [ST_I_PX_COMP_RSP]      = ME_NEW_PX("comp_rsp",      "http_comp_responses_total",          FN_COUNTER, FF_U64, p.http.comp_rsp,        STATS_PX_CAP__FB_, "Total number of HTTP responses that were compressed for this object since the worker process started"),
-       [ST_I_PX_LASTSESS]      = ME_NEW_BE("lastsess",      "last_session_seconds",               FN_AGE,     FF_S32, last_sess,              STATS_PX_CAP___BS, "How long ago some traffic was seen on this object on this worker process, in seconds"),
+       [ST_I_PX_REQ_TOT]       = ME_NEW_BE_SHARED("req_tot",       "http_requests_total",                FN_COUNTER, FF_U64, p.http.cum_req,         STATS_PX_CAP__FBS, "Total number of HTTP requests processed by this object since the worker process started"),
+       [ST_I_PX_CLI_ABRT]      = ME_NEW_BE_SHARED("cli_abrt",      "client_aborts_total",                FN_COUNTER, FF_U64, cli_aborts,             STATS_PX_CAP___BS, "Total number of requests or connections aborted by the client since the worker process started"),
+       [ST_I_PX_SRV_ABRT]      = ME_NEW_BE_SHARED("srv_abrt",      "server_aborts_total",                FN_COUNTER, FF_U64, srv_aborts,             STATS_PX_CAP___BS, "Total number of requests or connections aborted by the server since the worker process started"),
+       [ST_I_PX_COMP_IN]       = ME_NEW_PX_SHARED("comp_in",       "http_comp_bytes_in_total",           FN_COUNTER, FF_U64, comp_in[COMP_DIR_RES],  STATS_PX_CAP__FB_, "Total number of bytes submitted to the HTTP compressor for this object since the worker process started"),
+       [ST_I_PX_COMP_OUT]      = ME_NEW_PX_SHARED("comp_out",      "http_comp_bytes_out_total",          FN_COUNTER, FF_U64, comp_out[COMP_DIR_RES], STATS_PX_CAP__FB_, "Total number of bytes emitted by the HTTP compressor for this object since the worker process started"),
+       [ST_I_PX_COMP_BYP]      = ME_NEW_PX_SHARED("comp_byp",      "http_comp_bytes_bypassed_total",     FN_COUNTER, FF_U64, comp_byp[COMP_DIR_RES], STATS_PX_CAP__FB_, "Total number of bytes that bypassed HTTP compression for this object since the worker process started (CPU/memory/bandwidth limitation)"),
+       [ST_I_PX_COMP_RSP]      = ME_NEW_PX_SHARED("comp_rsp",      "http_comp_responses_total",          FN_COUNTER, FF_U64, p.http.comp_rsp,        STATS_PX_CAP__FB_, "Total number of HTTP responses that were compressed for this object since the worker process started"),
+       [ST_I_PX_LASTSESS]      = ME_NEW_BE_SHARED("lastsess",      "last_session_seconds",               FN_AGE,     FF_S32, last_sess,              STATS_PX_CAP___BS, "How long ago some traffic was seen on this object on this worker process, in seconds"),
        [ST_I_PX_LAST_CHK]                      = { .name = "last_chk",                    .alt_name = NULL,                              .desc = "Short description of the latest health check report for this server (see also check_desc)" },
        [ST_I_PX_LAST_AGT]                      = { .name = "last_agt",                    .alt_name = NULL,                              .desc = "Short description of the latest agent check report for this server (see also agent_desc)" },
        [ST_I_PX_QTIME]                         = { .name = "qtime",                       .alt_name = "queue_time_average_seconds",      .desc = "Time spent in the queue, in milliseconds, averaged over the 1024 last requests (backend/server)", .cap = STATS_PX_CAP___BS },
@@ -129,24 +154,24 @@ const struct stat_col stat_cols_px[ST_I_PX_MAX] = {
        [ST_I_PX_COOKIE]                        = { .name = "cookie",                      .alt_name = NULL,                              .desc = "Backend's cookie name or Server's cookie value, shown only if show-legends is set, or at levels oper/admin for the CLI" },
        [ST_I_PX_MODE]                          = { .name = "mode",                        .alt_name = NULL,                              .desc = "'mode' setting (tcp/http/health/cli/spop)" },
        [ST_I_PX_ALGO]                          = { .name = "algo",                        .alt_name = NULL,                              .desc = "Backend's load balancing algorithm, shown only if show-legends is set, or at levels oper/admin for the CLI" },
-       [ST_I_PX_CONN_RATE]     = ME_NEW_FE("conn_rate",     NULL,                            FN_RATE,    FF_U32, conn_per_sec,           STATS_PX_CAP__F__, "Number of new connections accepted over the last second on the frontend for this worker process"),
+       [ST_I_PX_CONN_RATE]     = ME_NEW_FE_SHARED("conn_rate",     NULL,                            FN_RATE,    FF_U32, conn_per_sec,           STATS_PX_CAP__F__, "Number of new connections accepted over the last second on the frontend for this worker process"),
        [ST_I_PX_CONN_RATE_MAX]                 = { .name = "conn_rate_max",               .alt_name = "connections_rate_max",            .desc = "Highest value of connections per second observed since the worker process started", .cap = STATS_PX_CAP__F__ },
-       [ST_I_PX_CONN_TOT]      = ME_NEW_FE("conn_tot",      "connections_total",             FN_COUNTER, FF_U64, cum_conn,               STATS_PX_CAP_LF__, "Total number of new connections accepted on this frontend since the worker process started"),
-       [ST_I_PX_INTERCEPTED]   = ME_NEW_FE("intercepted",   "intercepted_requests_total",    FN_COUNTER, FF_U64, intercepted_req,        STATS_PX_CAP__F__, "Total number of HTTP requests intercepted on the frontend (redirects/stats/services) since the worker process started"),
-       [ST_I_PX_DCON]          = ME_NEW_FE("dcon",          "denied_connections_total",      FN_COUNTER, FF_U64, denied_conn,            STATS_PX_CAP_LF__, "Total number of incoming connections blocked on a listener/frontend by a tcp-request connection rule since the worker process started"),
-       [ST_I_PX_DSES]          = ME_NEW_FE("dses",          "denied_sessions_total",         FN_COUNTER, FF_U64, denied_sess,            STATS_PX_CAP_LF__, "Total number of incoming sessions blocked on a listener/frontend by a tcp-request connection rule since the worker process started"),
-       [ST_I_PX_WREW]          = ME_NEW_PX("wrew",          "failed_header_rewriting_total", FN_COUNTER, FF_U64, failed_rewrites,        STATS_PX_CAP_LFBS, "Total number of failed HTTP header rewrites since the worker process started"),
-       [ST_I_PX_CONNECT]       = ME_NEW_BE("connect",       "connection_attempts_total",     FN_COUNTER, FF_U64, connect,                STATS_PX_CAP___BS, "Total number of outgoing connection attempts on this backend/server since the worker process started"),
-       [ST_I_PX_REUSE]         = ME_NEW_BE("reuse",         "connection_reuses_total",       FN_COUNTER, FF_U64, reuse,                  STATS_PX_CAP___BS, "Total number of reused connection on this backend/server since the worker process started"),
-       [ST_I_PX_CACHE_LOOKUPS] = ME_NEW_PX("cache_lookups", "http_cache_lookups_total",      FN_COUNTER, FF_U64, p.http.cache_lookups,   STATS_PX_CAP__FB_, "Total number of HTTP requests looked up in the cache on this frontend/backend since the worker process started"),
-       [ST_I_PX_CACHE_HITS]    = ME_NEW_PX("cache_hits",    "http_cache_hits_total",         FN_COUNTER, FF_U64, p.http.cache_hits,      STATS_PX_CAP__FB_, "Total number of HTTP requests not found in the cache on this frontend/backend since the worker process started"),
+       [ST_I_PX_CONN_TOT]      = ME_NEW_FE_SHARED("conn_tot",      "connections_total",             FN_COUNTER, FF_U64, cum_conn,               STATS_PX_CAP_LF__, "Total number of new connections accepted on this frontend since the worker process started"),
+       [ST_I_PX_INTERCEPTED]   = ME_NEW_FE_SHARED("intercepted",   "intercepted_requests_total",    FN_COUNTER, FF_U64, intercepted_req,        STATS_PX_CAP__F__, "Total number of HTTP requests intercepted on the frontend (redirects/stats/services) since the worker process started"),
+       [ST_I_PX_DCON]          = ME_NEW_FE_SHARED("dcon",          "denied_connections_total",      FN_COUNTER, FF_U64, denied_conn,            STATS_PX_CAP_LF__, "Total number of incoming connections blocked on a listener/frontend by a tcp-request connection rule since the worker process started"),
+       [ST_I_PX_DSES]          = ME_NEW_FE_SHARED("dses",          "denied_sessions_total",         FN_COUNTER, FF_U64, denied_sess,            STATS_PX_CAP_LF__, "Total number of incoming sessions blocked on a listener/frontend by a tcp-request connection rule since the worker process started"),
+       [ST_I_PX_WREW]          = ME_NEW_PX_SHARED("wrew",          "failed_header_rewriting_total", FN_COUNTER, FF_U64, failed_rewrites,        STATS_PX_CAP_LFBS, "Total number of failed HTTP header rewrites since the worker process started"),
+       [ST_I_PX_CONNECT]       = ME_NEW_BE_SHARED("connect",       "connection_attempts_total",     FN_COUNTER, FF_U64, connect,                STATS_PX_CAP___BS, "Total number of outgoing connection attempts on this backend/server since the worker process started"),
+       [ST_I_PX_REUSE]         = ME_NEW_BE_SHARED("reuse",         "connection_reuses_total",       FN_COUNTER, FF_U64, reuse,                  STATS_PX_CAP___BS, "Total number of reused connection on this backend/server since the worker process started"),
+       [ST_I_PX_CACHE_LOOKUPS] = ME_NEW_PX_SHARED("cache_lookups", "http_cache_lookups_total",      FN_COUNTER, FF_U64, p.http.cache_lookups,   STATS_PX_CAP__FB_, "Total number of HTTP requests looked up in the cache on this frontend/backend since the worker process started"),
+       [ST_I_PX_CACHE_HITS]    = ME_NEW_PX_SHARED("cache_hits",    "http_cache_hits_total",         FN_COUNTER, FF_U64, p.http.cache_hits,      STATS_PX_CAP__FB_, "Total number of HTTP requests not found in the cache on this frontend/backend since the worker process started"),
        [ST_I_PX_SRV_ICUR]                      = { .name = "srv_icur",                    .alt_name = "idle_connections_current",        .desc = "Current number of idle connections available for reuse on this server", .cap = STATS_PX_CAP____S },
        [ST_I_PX_SRV_ILIM]                      = { .name = "src_ilim",                    .alt_name = "idle_connections_limit",          .desc = "Limit on the number of available idle connections on this server (server 'pool_max_conn' directive)", .cap = STATS_PX_CAP____S },
        [ST_I_PX_QT_MAX]                        = { .name = "qtime_max",                   .alt_name = "max_queue_time_seconds",          .desc = "Maximum observed time spent in the queue, in milliseconds (backend/server)", .cap = STATS_PX_CAP___BS },
        [ST_I_PX_CT_MAX]                        = { .name = "ctime_max",                   .alt_name = "max_connect_time_seconds",        .desc = "Maximum observed time spent waiting for a connection to complete, in milliseconds (backend/server)", .cap = STATS_PX_CAP___BS },
        [ST_I_PX_RT_MAX]                        = { .name = "rtime_max",                   .alt_name = "max_response_time_seconds",       .desc = "Maximum observed time spent waiting for a server response, in milliseconds (backend/server)", .cap = STATS_PX_CAP___BS },
        [ST_I_PX_TT_MAX]                        = { .name = "ttime_max",                   .alt_name = "max_total_time_seconds",          .desc = "Maximum observed total request+response time (request+queue+connect+response+processing), in milliseconds (backend/server)", .cap = STATS_PX_CAP___BS },
-       [ST_I_PX_EINT]          = ME_NEW_PX("eint",          "internal_errors_total",         FN_COUNTER, FF_U64, internal_errors,        STATS_PX_CAP_LFBS, "Total number of internal errors since process started"),
+       [ST_I_PX_EINT]          = ME_NEW_PX_SHARED("eint",          "internal_errors_total",         FN_COUNTER, FF_U64, internal_errors,        STATS_PX_CAP_LFBS, "Total number of internal errors since process started"),
        [ST_I_PX_IDLE_CONN_CUR]                 = { .name = "idle_conn_cur",               .alt_name = "unsafe_idle_connections_current", .desc = "Current number of unsafe idle connections", .cap = STATS_PX_CAP____S},
        [ST_I_PX_SAFE_CONN_CUR]                 = { .name = "safe_conn_cur",               .alt_name = "safe_idle_connections_current",   .desc = "Current number of safe idle connections", .cap = STATS_PX_CAP____S},
        [ST_I_PX_USED_CONN_CUR]                 = { .name = "used_conn_cur",               .alt_name = "used_connections_current",        .desc = "Current number of connections in use", .cap = STATS_PX_CAP____S},
@@ -157,13 +182,13 @@ const struct stat_col stat_cols_px[ST_I_PX_MAX] = {
        [ST_I_PX_AGG_CHECK_STATUS]              = { .name = "agg_check_status",            .alt_name = "agg_check_status",                .desc = "Backend's aggregated gauge of servers' state check status", .cap = STATS_PX_CAP___B_ },
        [ST_I_PX_SRID]                          = { .name = "srid",                        .alt_name = NULL,                              .desc = "Server id revision, to prevent server id reuse mixups" },
        [ST_I_PX_SESS_OTHER]                    = { .name = "sess_other",                  .alt_name = NULL,                              .desc = "Total number of sessions other than HTTP since process started" },
-       [ST_I_PX_H1SESS]        = ME_NEW_FE("h1sess",        NULL,                            FN_COUNTER, FF_U64, cum_sess_ver[0],        STATS_PX_CAP__F__, "Total number of HTTP/1 sessions since process started"),
-       [ST_I_PX_H2SESS]        = ME_NEW_FE("h2sess",        NULL,                            FN_COUNTER, FF_U64, cum_sess_ver[1],        STATS_PX_CAP__F__, "Total number of HTTP/2 sessions since process started"),
-       [ST_I_PX_H3SESS]        = ME_NEW_FE("h3sess",        NULL,                            FN_COUNTER, FF_U64, cum_sess_ver[2],        STATS_PX_CAP__F__, "Total number of HTTP/3 sessions since process started"),
-       [ST_I_PX_REQ_OTHER]     = ME_NEW_FE("req_other",     NULL,                            FN_COUNTER, FF_U64, p.http.cum_req[0],      STATS_PX_CAP__F__, "Total number of sessions other than HTTP processed by this object since the worker process started"),
-       [ST_I_PX_H1REQ]         = ME_NEW_FE("h1req",         NULL,                            FN_COUNTER, FF_U64, p.http.cum_req[1],      STATS_PX_CAP__F__, "Total number of HTTP/1 sessions processed by this object since the worker process started"),
-       [ST_I_PX_H2REQ]         = ME_NEW_FE("h2req",         NULL,                            FN_COUNTER, FF_U64, p.http.cum_req[2],      STATS_PX_CAP__F__, "Total number of hTTP/2 sessions processed by this object since the worker process started"),
-       [ST_I_PX_H3REQ]         = ME_NEW_FE("h3req",         NULL,                            FN_COUNTER, FF_U64, p.http.cum_req[3],      STATS_PX_CAP__F__, "Total number of HTTP/3 sessions processed by this object since the worker process started"),
+       [ST_I_PX_H1SESS]        = ME_NEW_FE_SHARED("h1sess",        NULL,                            FN_COUNTER, FF_U64, cum_sess_ver[0],        STATS_PX_CAP__F__, "Total number of HTTP/1 sessions since process started"),
+       [ST_I_PX_H2SESS]        = ME_NEW_FE_SHARED("h2sess",        NULL,                            FN_COUNTER, FF_U64, cum_sess_ver[1],        STATS_PX_CAP__F__, "Total number of HTTP/2 sessions since process started"),
+       [ST_I_PX_H3SESS]        = ME_NEW_FE_SHARED("h3sess",        NULL,                            FN_COUNTER, FF_U64, cum_sess_ver[2],        STATS_PX_CAP__F__, "Total number of HTTP/3 sessions since process started"),
+       [ST_I_PX_REQ_OTHER]     = ME_NEW_FE_SHARED("req_other",     NULL,                            FN_COUNTER, FF_U64, p.http.cum_req[0],      STATS_PX_CAP__F__, "Total number of sessions other than HTTP processed by this object since the worker process started"),
+       [ST_I_PX_H1REQ]         = ME_NEW_FE_SHARED("h1req",         NULL,                            FN_COUNTER, FF_U64, p.http.cum_req[1],      STATS_PX_CAP__F__, "Total number of HTTP/1 sessions processed by this object since the worker process started"),
+       [ST_I_PX_H2REQ]         = ME_NEW_FE_SHARED("h2req",         NULL,                            FN_COUNTER, FF_U64, p.http.cum_req[2],      STATS_PX_CAP__F__, "Total number of hTTP/2 sessions processed by this object since the worker process started"),
+       [ST_I_PX_H3REQ]         = ME_NEW_FE_SHARED("h3req",         NULL,                            FN_COUNTER, FF_U64, p.http.cum_req[3],      STATS_PX_CAP__F__, "Total number of HTTP/3 sessions processed by this object since the worker process started"),
        [ST_I_PX_PROTO]                         = { .name = "proto",                       .alt_name = NULL,                              .desc = "Protocol" },
 };
 
@@ -220,9 +245,9 @@ static int stcol_hide(enum stat_idx_px idx, enum obj_type *objt)
 
        case ST_I_PX_LASTSESS:
                if (srv)
-                       return !srv->counters.last_sess;
+                       return !HA_ATOMIC_LOAD(&srv->counters.shared->last_sess);
                else if (px)
-                       return !px->be_counters.last_sess;
+                       return !HA_ATOMIC_LOAD(&px->be_counters.shared->last_sess);
                else
                        return 0;
 
@@ -256,13 +281,19 @@ static struct field me_generate_field(const struct stat_col *col,
        switch (cap) {
        case STATS_PX_CAP_FE:
        case STATS_PX_CAP_LI:
-               counter = (char *)counters + col->metric.offset[0];
+               if (col->flags & STAT_COL_FL_SHARED)
+                       counter = (char *)((struct fe_counters *)counters)->shared + col->metric.offset[0];
+               else
+                       counter = (char *)counters + col->metric.offset[0];
                wrong_side = !(col->cap & (STATS_PX_CAP_FE|STATS_PX_CAP_LI));
                break;
 
        case STATS_PX_CAP_BE:
        case STATS_PX_CAP_SRV:
-               counter = (char *)counters + col->metric.offset[1];
+               if (col->flags & STAT_COL_FL_SHARED)
+                       counter = (char *)((struct be_counters *)counters)->shared + col->metric.offset[1];
+               else
+                       counter = (char *)counters + col->metric.offset[1];
                wrong_side = !(col->cap & (STATS_PX_CAP_BE|STATS_PX_CAP_SRV));
                break;
 
@@ -278,13 +309,13 @@ static struct field me_generate_field(const struct stat_col *col,
        if (idx == ST_I_PX_REQ_TOT && cap == STATS_PX_CAP_FE && !stat_file) {
                struct proxy *px = __objt_proxy(objt);
                const size_t nb_reqs =
-                 sizeof(px->fe_counters.p.http.cum_req) /
-                 sizeof(*px->fe_counters.p.http.cum_req);
+                 sizeof(px->fe_counters.shared->p.http.cum_req) /
+                 sizeof(*px->fe_counters.shared->p.http.cum_req);
                uint64_t total_req = 0;
                int i;
 
                for (i = 0; i < nb_reqs; i++)
-                       total_req += px->fe_counters.p.http.cum_req[i];
+                       total_req += HA_ATOMIC_LOAD(&px->fe_counters.shared->p.http.cum_req[i]);
                return mkf_u64(FN_COUNTER, total_req);
        }
 
@@ -311,7 +342,11 @@ static struct field me_generate_field(const struct stat_col *col,
        if (fn == FN_COUNTER) {
                switch (stcol_format(col)) {
                case FF_U64:
-                       value = mkf_u64(FN_COUNTER, *(uint64_t *)counter);
+                       if (col->flags & STAT_COL_FL_SHARED)
+                               value = mkf_u64(FN_COUNTER, HA_ATOMIC_LOAD((uint64_t *)counter));
+
+                       else
+                               value = mkf_u64(FN_COUNTER, *(uint64_t *)counter);
                        break;
                default:
                        /* only FF_U64 counters currently use generic metric calculation */
@@ -324,7 +359,13 @@ static struct field me_generate_field(const struct stat_col *col,
                value = mkf_u32(FN_RATE, read_freq_ctr(counter));
        }
        else if (fn == FN_AGE) {
-               unsigned long age = *(unsigned long *)counter;
+               unsigned long age;
+
+               if (col->flags & STAT_COL_FL_SHARED)
+                       age = HA_ATOMIC_LOAD((unsigned long *)counter);
+               else
+                       age = *(unsigned long *)counter;
+
                if (age)
                        age = ns_to_sec(now_ns) - age;
 
@@ -431,11 +472,11 @@ int stats_fill_fe_line(struct proxy *px, int flags, struct field *line, int len,
                                int i;
                                uint64_t total_sess;
                                size_t nb_sess =
-                                       sizeof(px->fe_counters.cum_sess_ver) / sizeof(*px->fe_counters.cum_sess_ver);
+                                       sizeof(px->fe_counters.shared->cum_sess_ver) / sizeof(*px->fe_counters.shared->cum_sess_ver);
 
-                               total_sess = px->fe_counters.cum_sess;
+                               total_sess = HA_ATOMIC_LOAD(&px->fe_counters.shared->cum_sess);
                                for (i = 0; i < nb_sess; i++)
-                                       total_sess -= px->fe_counters.cum_sess_ver[i];
+                                       total_sess -= HA_ATOMIC_LOAD(&px->fe_counters.shared->cum_sess_ver[i]);
                                total_sess = (int64_t)total_sess < 0 ? 0 : total_sess;
                                field = mkf_u64(FN_COUNTER, total_sess);
                                break;
@@ -770,7 +811,7 @@ int stats_fill_sv_line(struct proxy *px, struct server *sv, int flags,
        if (index == NULL || *index == ST_I_PX_QTIME ||
            *index == ST_I_PX_CTIME || *index == ST_I_PX_RTIME ||
            *index == ST_I_PX_TTIME) {
-               srv_samples_counter = (px->mode == PR_MODE_HTTP) ? sv->counters.p.http.cum_req : sv->counters.cum_lbconn;
+               srv_samples_counter = (px->mode == PR_MODE_HTTP) ? HA_ATOMIC_LOAD(&sv->counters.shared->p.http.cum_req) : HA_ATOMIC_LOAD(&sv->counters.shared->cum_lbconn);
                if (srv_samples_counter < TIME_STATS_SAMPLES && srv_samples_counter > 0)
                        srv_samples_window = srv_samples_counter;
        }
@@ -1149,7 +1190,7 @@ int stats_fill_be_line(struct proxy *px, int flags, struct field *line, int len,
        if (!index || *index == ST_I_PX_QTIME ||
            *index == ST_I_PX_CTIME || *index == ST_I_PX_RTIME ||
            *index == ST_I_PX_TTIME) {
-               be_samples_counter = (px->mode == PR_MODE_HTTP) ? px->be_counters.p.http.cum_req : px->be_counters.cum_lbconn;
+               be_samples_counter = (px->mode == PR_MODE_HTTP) ? HA_ATOMIC_LOAD(&px->be_counters.shared->p.http.cum_req) : HA_ATOMIC_LOAD(&px->be_counters.shared->cum_lbconn);
                if (be_samples_counter < TIME_STATS_SAMPLES && be_samples_counter > 0)
                        be_samples_window = be_samples_counter;
        }
index 46f77cc98cdaabf343b1bb1926ab9f6de1d92aac..f830d58a56f06ec9fa1ca591b4afc855e7c6e8d4 100644 (file)
@@ -823,14 +823,14 @@ void stream_process_counters(struct stream *s)
        bytes = s->req.total - s->logs.bytes_in;
        s->logs.bytes_in = s->req.total;
        if (bytes) {
-               _HA_ATOMIC_ADD(&sess->fe->fe_counters.bytes_in, bytes);
-               _HA_ATOMIC_ADD(&s->be->be_counters.bytes_in,    bytes);
+               _HA_ATOMIC_ADD(&sess->fe->fe_counters.shared->bytes_in, bytes);
+               _HA_ATOMIC_ADD(&s->be->be_counters.shared->bytes_in,    bytes);
 
                if (objt_server(s->target))
-                       _HA_ATOMIC_ADD(&__objt_server(s->target)->counters.bytes_in, bytes);
+                       _HA_ATOMIC_ADD(&__objt_server(s->target)->counters.shared->bytes_in, bytes);
 
                if (sess->listener && sess->listener->counters)
-                       _HA_ATOMIC_ADD(&sess->listener->counters->bytes_in, bytes);
+                       _HA_ATOMIC_ADD(&sess->listener->counters->shared->bytes_in, bytes);
 
                for (i = 0; i < global.tune.nb_stk_ctr; i++) {
                        if (!stkctr_inc_bytes_in_ctr(&s->stkctr[i], bytes))
@@ -841,14 +841,14 @@ void stream_process_counters(struct stream *s)
        bytes = s->res.total - s->logs.bytes_out;
        s->logs.bytes_out = s->res.total;
        if (bytes) {
-               _HA_ATOMIC_ADD(&sess->fe->fe_counters.bytes_out, bytes);
-               _HA_ATOMIC_ADD(&s->be->be_counters.bytes_out,    bytes);
+               _HA_ATOMIC_ADD(&sess->fe->fe_counters.shared->bytes_out, bytes);
+               _HA_ATOMIC_ADD(&s->be->be_counters.shared->bytes_out,    bytes);
 
                if (objt_server(s->target))
-                       _HA_ATOMIC_ADD(&__objt_server(s->target)->counters.bytes_out, bytes);
+                       _HA_ATOMIC_ADD(&__objt_server(s->target)->counters.shared->bytes_out, bytes);
 
                if (sess->listener && sess->listener->counters)
-                       _HA_ATOMIC_ADD(&sess->listener->counters->bytes_out, bytes);
+                       _HA_ATOMIC_ADD(&sess->listener->counters->shared->bytes_out, bytes);
 
                for (i = 0; i < global.tune.nb_stk_ctr; i++) {
                        if (!stkctr_inc_bytes_out_ctr(&s->stkctr[i], bytes))
@@ -1012,9 +1012,9 @@ void sess_set_term_flags(struct stream *s)
        if (!(s->flags & SF_FINST_MASK)) {
                if (s->scb->state == SC_ST_INI) {
                        /* anything before REQ in fact */
-                       _HA_ATOMIC_INC(&strm_fe(s)->fe_counters.failed_req);
+                       _HA_ATOMIC_INC(&strm_fe(s)->fe_counters.shared->failed_req);
                        if (strm_li(s) && strm_li(s)->counters)
-                               _HA_ATOMIC_INC(&strm_li(s)->counters->failed_req);
+                               _HA_ATOMIC_INC(&strm_li(s)->counters->shared->failed_req);
 
                        s->flags |= SF_FINST_R;
                }
@@ -1061,7 +1061,7 @@ enum act_return process_use_service(struct act_rule *rule, struct proxy *px,
 
        if (rule->from != ACT_F_HTTP_REQ) {
                if (sess->fe == s->be) /* report it if the request was intercepted by the frontend */
-                       _HA_ATOMIC_INC(&sess->fe->fe_counters.intercepted_req);
+                       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->intercepted_req);
 
                /* The flag SF_ASSIGNED prevent from server assignment. */
                s->flags |= SF_ASSIGNED;
@@ -1856,12 +1856,12 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                        sc_shutdown(scf);
                        if (!(req->analysers) && !(res->analysers)) {
                                COUNT_IF(1, "Report a client abort (no analysers)");
-                               _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->cli_aborts);
+                               _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->cli_aborts);
                                if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->cli_aborts);
+                                       _HA_ATOMIC_INC(&sess->listener->counters->shared->cli_aborts);
                                if (srv)
-                                       _HA_ATOMIC_INC(&srv->counters.cli_aborts);
+                                       _HA_ATOMIC_INC(&srv->counters.shared->cli_aborts);
                                if (!(s->flags & SF_ERR_MASK))
                                        s->flags |= SF_ERR_CLICL;
                                if (!(s->flags & SF_FINST_MASK))
@@ -1874,17 +1874,17 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                if (sc_state_in(scb->state, SC_SB_EST|SC_SB_DIS)) {
                        sc_abort(scb);
                        sc_shutdown(scb);
-                       _HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
+                       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_resp);
                        if (srv)
-                               _HA_ATOMIC_INC(&srv->counters.failed_resp);
+                               _HA_ATOMIC_INC(&srv->counters.shared->failed_resp);
                        if (!(req->analysers) && !(res->analysers)) {
                                COUNT_IF(1, "Report a client abort (no analysers)");
-                               _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.srv_aborts);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->srv_aborts);
+                               _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->srv_aborts);
                                if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->srv_aborts);
+                                       _HA_ATOMIC_INC(&sess->listener->counters->shared->srv_aborts);
                                if (srv)
-                                       _HA_ATOMIC_INC(&srv->counters.srv_aborts);
+                                       _HA_ATOMIC_INC(&srv->counters.shared->srv_aborts);
                                if (!(s->flags & SF_ERR_MASK))
                                        s->flags |= SF_ERR_SRVCL;
                                if (!(s->flags & SF_FINST_MASK))
@@ -2188,32 +2188,32 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                        req->analysers &= AN_REQ_FLT_END;
                        channel_auto_close(req);
                        if (scf->flags & SC_FL_ERROR) {
-                               _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->cli_aborts);
+                               _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->cli_aborts);
                                if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->cli_aborts);
+                                       _HA_ATOMIC_INC(&sess->listener->counters->shared->cli_aborts);
                                if (srv)
-                                       _HA_ATOMIC_INC(&srv->counters.cli_aborts);
+                                       _HA_ATOMIC_INC(&srv->counters.shared->cli_aborts);
                                s->flags |= SF_ERR_CLICL;
                                COUNT_IF(1, "Report unhandled client error");
                        }
                        else if (req->flags & CF_READ_TIMEOUT) {
-                               _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->cli_aborts);
+                               _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->cli_aborts);
                                if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->cli_aborts);
+                                       _HA_ATOMIC_INC(&sess->listener->counters->shared->cli_aborts);
                                if (srv)
-                                       _HA_ATOMIC_INC(&srv->counters.cli_aborts);
+                                       _HA_ATOMIC_INC(&srv->counters.shared->cli_aborts);
                                s->flags |= SF_ERR_CLITO;
                                COUNT_IF(1, "Report unhandled client timeout (RD)");
                        }
                        else {
-                               _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.srv_aborts);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->srv_aborts);
+                               _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->srv_aborts);
                                if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->srv_aborts);
+                                       _HA_ATOMIC_INC(&sess->listener->counters->shared->srv_aborts);
                                if (srv)
-                                       _HA_ATOMIC_INC(&srv->counters.srv_aborts);
+                                       _HA_ATOMIC_INC(&srv->counters.shared->srv_aborts);
                                s->flags |= SF_ERR_SRVTO;
                                COUNT_IF(1, "Report unhandled server timeout (WR)");
                        }
@@ -2237,32 +2237,32 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                        res->analysers &= AN_RES_FLT_END;
                        channel_auto_close(res);
                        if (scb->flags & SC_FL_ERROR) {
-                               _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.srv_aborts);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->srv_aborts);
+                               _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->srv_aborts);
                                if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->srv_aborts);
+                                       _HA_ATOMIC_INC(&sess->listener->counters->shared->srv_aborts);
                                if (srv)
-                                       _HA_ATOMIC_INC(&srv->counters.srv_aborts);
+                                       _HA_ATOMIC_INC(&srv->counters.shared->srv_aborts);
                                s->flags |= SF_ERR_SRVCL;
                                COUNT_IF(1, "Report unhandled server error");
                        }
                        else if (res->flags & CF_READ_TIMEOUT) {
-                               _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.srv_aborts);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->srv_aborts);
+                               _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->srv_aborts);
                                if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->srv_aborts);
+                                       _HA_ATOMIC_INC(&sess->listener->counters->shared->srv_aborts);
                                if (srv)
-                                       _HA_ATOMIC_INC(&srv->counters.srv_aborts);
+                                       _HA_ATOMIC_INC(&srv->counters.shared->srv_aborts);
                                s->flags |= SF_ERR_SRVTO;
                                COUNT_IF(1, "Report unhandled server timeout (RD)");
                        }
                        else {
-                               _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->cli_aborts);
+                               _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->cli_aborts);
                                if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->cli_aborts);
+                                       _HA_ATOMIC_INC(&sess->listener->counters->shared->cli_aborts);
                                if (srv)
-                                       _HA_ATOMIC_INC(&srv->counters.cli_aborts);
+                                       _HA_ATOMIC_INC(&srv->counters.shared->cli_aborts);
                                s->flags |= SF_ERR_CLITO;
                                COUNT_IF(1, "Report unhandled client timeout (WR)");
                        }
@@ -2633,12 +2633,12 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                n = 0;
 
                        if (sess->fe->mode == PR_MODE_HTTP) {
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.p.http.rsp[n]);
+                               _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->p.http.rsp[n]);
                        }
                        if ((s->flags & SF_BE_ASSIGNED) &&
                            (s->be->mode == PR_MODE_HTTP)) {
-                               _HA_ATOMIC_INC(&s->be->be_counters.p.http.rsp[n]);
-                               _HA_ATOMIC_INC(&s->be->be_counters.p.http.cum_req);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->p.http.rsp[n]);
+                               _HA_ATOMIC_INC(&s->be->be_counters.shared->p.http.cum_req);
                        }
                }
 
@@ -2703,7 +2703,7 @@ void stream_update_time_stats(struct stream *s)
        srv = objt_server(s->target);
        if (srv) {
                samples_window = (((s->be->mode == PR_MODE_HTTP) ?
-                       srv->counters.p.http.cum_req : srv->counters.cum_lbconn) > TIME_STATS_SAMPLES) ? TIME_STATS_SAMPLES : 0;
+                       HA_ATOMIC_LOAD(&srv->counters.shared->p.http.cum_req) : HA_ATOMIC_LOAD(&srv->counters.shared->cum_lbconn)) > TIME_STATS_SAMPLES) ? TIME_STATS_SAMPLES : 0;
                swrate_add_dynamic(&srv->counters.q_time, samples_window, t_queue);
                swrate_add_dynamic(&srv->counters.c_time, samples_window, t_connect);
                swrate_add_dynamic(&srv->counters.d_time, samples_window, t_data);
@@ -2714,7 +2714,7 @@ void stream_update_time_stats(struct stream *s)
                HA_ATOMIC_UPDATE_MAX(&srv->counters.ttime_max, t_close);
        }
        samples_window = (((s->be->mode == PR_MODE_HTTP) ?
-               s->be->be_counters.p.http.cum_req : s->be->be_counters.cum_lbconn) > TIME_STATS_SAMPLES) ? TIME_STATS_SAMPLES : 0;
+               HA_ATOMIC_LOAD(&s->be->be_counters.shared->p.http.cum_req) : HA_ATOMIC_LOAD(&s->be->be_counters.shared->cum_lbconn)) > TIME_STATS_SAMPLES) ? TIME_STATS_SAMPLES : 0;
        swrate_add_dynamic(&s->be->be_counters.q_time, samples_window, t_queue);
        swrate_add_dynamic(&s->be->be_counters.c_time, samples_window, t_connect);
        swrate_add_dynamic(&s->be->be_counters.d_time, samples_window, t_data);
index 8a4fd2f908e9a8702e8d82c3e2cded23cfff940a..02275e664df3c1539493592d529e4306c2fd98d6 100644 (file)
@@ -397,16 +397,16 @@ static enum act_return tcp_exec_action_silent_drop(struct act_rule *rule, struct
                strm->req.analysers &= AN_REQ_FLT_END;
                strm->res.analysers &= AN_RES_FLT_END;
                if (strm->flags & SF_BE_ASSIGNED)
-                       _HA_ATOMIC_INC(&strm->be->be_counters.denied_req);
+                       _HA_ATOMIC_INC(&strm->be->be_counters.shared->denied_req);
                if (!(strm->flags & SF_ERR_MASK))
                        strm->flags |= SF_ERR_PRXCOND;
                if (!(strm->flags & SF_FINST_MASK))
                        strm->flags |= SF_FINST_R;
        }
 
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->denied_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->denied_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->denied_req);
 
        return ACT_RET_ABRT;
 }
index c81f271faa90ea3dd925a30e2c7552db22bab0b2..6c894660500383e66a17dbc58bd001b7e220f833 100644 (file)
@@ -264,25 +264,25 @@ resume_execution:
        return 0;
 
  deny:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->denied_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->denied_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->denied_req);
        stream_report_term_evt(s->scf, strm_tevt_type_intercepted);
        goto reject;
 
  internal:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.internal_errors);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->internal_errors);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->internal_errors);
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
        stream_report_term_evt(s->scf, strm_tevt_type_internal_err);
        goto reject;
 
  invalid:
-       _HA_ATOMIC_INC(&sess->fe->fe_counters.failed_req);
+       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->failed_req);
        if (sess->listener && sess->listener->counters)
-               _HA_ATOMIC_INC(&sess->listener->counters->failed_req);
+               _HA_ATOMIC_INC(&sess->listener->counters->shared->failed_req);
        stream_report_term_evt(s->scf, strm_tevt_type_proto_err);
 
  reject:
@@ -486,31 +486,31 @@ resume_execution:
        return 0;
 
   deny:
-       _HA_ATOMIC_INC(&s->sess->fe->fe_counters.denied_resp);
-       _HA_ATOMIC_INC(&s->be->be_counters.denied_resp);
+       _HA_ATOMIC_INC(&s->sess->fe->fe_counters.shared->denied_resp);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->denied_resp);
        if (s->sess->listener && s->sess->listener->counters)
-               _HA_ATOMIC_INC(&s->sess->listener->counters->denied_resp);
+               _HA_ATOMIC_INC(&s->sess->listener->counters->shared->denied_resp);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.denied_resp);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->denied_resp);
        stream_report_term_evt(s->scb, strm_tevt_type_intercepted);
        goto reject;
 
  internal:
-       _HA_ATOMIC_INC(&s->sess->fe->fe_counters.internal_errors);
-       _HA_ATOMIC_INC(&s->be->be_counters.internal_errors);
+       _HA_ATOMIC_INC(&s->sess->fe->fe_counters.shared->internal_errors);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->internal_errors);
        if (s->sess->listener && s->sess->listener->counters)
-               _HA_ATOMIC_INC(&s->sess->listener->counters->internal_errors);
+               _HA_ATOMIC_INC(&s->sess->listener->counters->shared->internal_errors);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.internal_errors);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->internal_errors);
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
        stream_report_term_evt(s->scf, strm_tevt_type_internal_err);
        goto reject;
 
  invalid:
-       _HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
+       _HA_ATOMIC_INC(&s->be->be_counters.shared->failed_resp);
        if (objt_server(s->target))
-               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_resp);
+               _HA_ATOMIC_INC(&__objt_server(s->target)->counters.shared->failed_resp);
        stream_report_term_evt(s->scf, strm_tevt_type_proto_err);
 
  reject:
@@ -585,9 +585,9 @@ int tcp_exec_l4_rules(struct session *sess)
                        goto end;
                }
                else if (rule->action == ACT_ACTION_DENY) {
-                       _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_conn);
+                       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->denied_conn);
                        if (sess->listener && sess->listener->counters)
-                               _HA_ATOMIC_INC(&sess->listener->counters->denied_conn);
+                               _HA_ATOMIC_INC(&sess->listener->counters->shared->denied_conn);
 
                        result = 0;
                        goto end;
@@ -673,9 +673,9 @@ int tcp_exec_l5_rules(struct session *sess)
                        goto end;
                }
                else if (rule->action == ACT_ACTION_DENY) {
-                       _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_sess);
+                       _HA_ATOMIC_INC(&sess->fe->fe_counters.shared->denied_sess);
                        if (sess->listener && sess->listener->counters)
-                               _HA_ATOMIC_INC(&sess->listener->counters->denied_sess);
+                               _HA_ATOMIC_INC(&sess->listener->counters->shared->denied_sess);
 
                        result = 0;
                        goto end;