From 5495c884418e301d746f66eab015c1c4ad3d4cc7 Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Mon, 12 Jan 2026 04:25:34 +0100 Subject: [PATCH] MEDIUM: counters: Dynamically allocate per-thread group counters Instead of statically allocating the per-thread group counters, based on the max number of thread groups available, allocate them dynamically, based on the number of thread groups actually used. That way we can increase the maximum number of thread groups without using an unreasonable amount of memory. --- include/haproxy/backend.h | 2 +- include/haproxy/counters-t.h | 6 +++--- include/haproxy/proxy.h | 32 +++++++++++++++---------------- include/haproxy/server.h | 4 ++-- src/backend.c | 6 +++--- src/cache.c | 8 ++++---- src/check.c | 4 ++-- src/cli.c | 10 ++++++++-- src/counters.c | 11 ++++++++++- src/http_client.c | 10 ++++++++-- src/listener.c | 2 +- src/proxy.c | 6 +++++- src/server.c | 6 +++--- src/server_state.c | 2 +- src/session.c | 8 ++++++-- src/stats-file.c | 37 ++++++++++++++++++++++++++++++++---- src/stats-proxy.c | 4 ++-- src/stream.c | 6 +++++- 18 files changed, 113 insertions(+), 51 deletions(-) diff --git a/include/haproxy/backend.h b/include/haproxy/backend.h index 94ca8f8c5..70709480a 100644 --- a/include/haproxy/backend.h +++ b/include/haproxy/backend.h @@ -88,7 +88,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) { - if (be->be_counters.shared.tg[tgid - 1]) + if (be->be_counters.shared.tg && be->be_counters.shared.tg[tgid - 1]) HA_ATOMIC_STORE(&be->be_counters.shared.tg[tgid - 1]->last_sess, ns_to_sec(now_ns)); } diff --git a/include/haproxy/counters-t.h b/include/haproxy/counters-t.h index 2cdb4582b..fde3930dd 100644 --- a/include/haproxy/counters-t.h +++ b/include/haproxy/counters-t.h @@ -66,7 +66,7 @@ struct counters_shared { COUNTERS_SHARED; struct { COUNTERS_SHARED_TG; - } *tg[MAX_TGROUPS]; + } **tg; }; /* @@ -101,7 +101,7 @@ struct fe_counters_shared_tg { struct fe_counters_shared { COUNTERS_SHARED; - struct fe_counters_shared_tg *tg[MAX_TGROUPS]; + struct fe_counters_shared_tg **tg; }; /* counters used by listeners and frontends */ @@ -160,7 +160,7 @@ struct be_counters_shared_tg { struct be_counters_shared { COUNTERS_SHARED; - struct be_counters_shared_tg *tg[MAX_TGROUPS]; + struct be_counters_shared_tg **tg; }; /* counters used by servers and backends */ diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index 0288d6d41..9ddd46244 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -166,12 +166,12 @@ static inline int proxy_abrt_close(const struct proxy *px) /* 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) { - if (fe->fe_counters.shared.tg[tgid - 1]) + if (fe->fe_counters.shared.tg && fe->fe_counters.shared.tg[tgid - 1]) { _HA_ATOMIC_INC(&fe->fe_counters.shared.tg[tgid - 1]->cum_conn); - if (l && l->counters && l->counters->shared.tg[tgid - 1]) - _HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_conn); - if (fe->fe_counters.shared.tg[tgid - 1]) update_freq_ctr(&fe->fe_counters.shared.tg[tgid - 1]->conn_per_sec, 1); + } + if (l && l->counters && l->counters->shared.tg && l->counters->shared.tg[tgid - 1]) + _HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_conn); HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.cps_max, update_freq_ctr(&fe->fe_counters._conn_per_sec, 1)); } @@ -179,12 +179,12 @@ static inline void proxy_inc_fe_conn_ctr(struct listener *l, struct proxy *fe) /* 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) { - if (fe->fe_counters.shared.tg[tgid - 1]) + if (fe->fe_counters.shared.tg && fe->fe_counters.shared.tg[tgid - 1]) { _HA_ATOMIC_INC(&fe->fe_counters.shared.tg[tgid - 1]->cum_sess); - if (l && l->counters && l->counters->shared.tg[tgid - 1]) - _HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_sess); - if (fe->fe_counters.shared.tg[tgid - 1]) update_freq_ctr(&fe->fe_counters.shared.tg[tgid - 1]->sess_per_sec, 1); + } + if (l && l->counters && l->counters->shared.tg && l->counters->shared.tg[tgid - 1]) + _HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->cum_sess); HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.sps_max, update_freq_ctr(&fe->fe_counters._sess_per_sec, 1)); } @@ -199,19 +199,19 @@ static inline void proxy_inc_fe_cum_sess_ver_ctr(struct listener *l, struct prox http_ver > sizeof(fe->fe_counters.shared.tg[tgid - 1]->cum_sess_ver) / sizeof(*fe->fe_counters.shared.tg[tgid - 1]->cum_sess_ver)) return; - if (fe->fe_counters.shared.tg[tgid - 1]) + if (fe->fe_counters.shared.tg && fe->fe_counters.shared.tg[tgid - 1]) _HA_ATOMIC_INC(&fe->fe_counters.shared.tg[tgid - 1]->cum_sess_ver[http_ver - 1]); - if (l && l->counters && l->counters->shared.tg[tgid - 1]) + if (l && l->counters && l->counters->shared.tg && l->counters->shared.tg[tgid - 1]) _HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->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) { - if (be->be_counters.shared.tg[tgid - 1]) + if (be->be_counters.shared.tg && be->be_counters.shared.tg[tgid - 1]) { _HA_ATOMIC_INC(&be->be_counters.shared.tg[tgid - 1]->cum_sess); - if (be->be_counters.shared.tg[tgid - 1]) update_freq_ctr(&be->be_counters.shared.tg[tgid - 1]->sess_per_sec, 1); + } HA_ATOMIC_UPDATE_MAX(&be->be_counters.sps_max, update_freq_ctr(&be->be_counters._sess_per_sec, 1)); } @@ -226,12 +226,12 @@ static inline void proxy_inc_fe_req_ctr(struct listener *l, struct proxy *fe, if (http_ver >= sizeof(fe->fe_counters.shared.tg[tgid - 1]->p.http.cum_req) / sizeof(*fe->fe_counters.shared.tg[tgid - 1]->p.http.cum_req)) return; - if (fe->fe_counters.shared.tg[tgid - 1]) + if (fe->fe_counters.shared.tg && fe->fe_counters.shared.tg[tgid - 1]) { _HA_ATOMIC_INC(&fe->fe_counters.shared.tg[tgid - 1]->p.http.cum_req[http_ver]); - if (l && l->counters && l->counters->shared.tg[tgid - 1]) - _HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->p.http.cum_req[http_ver]); - if (fe->fe_counters.shared.tg[tgid - 1]) update_freq_ctr(&fe->fe_counters.shared.tg[tgid - 1]->req_per_sec, 1); + } + if (l && l->counters && l->counters->shared.tg && l->counters->shared.tg[tgid - 1]) + _HA_ATOMIC_INC(&l->counters->shared.tg[tgid - 1]->p.http.cum_req[http_ver]); HA_ATOMIC_UPDATE_MAX(&fe->fe_counters.p.http.rps_max, update_freq_ctr(&fe->fe_counters.p.http._req_per_sec, 1)); } diff --git a/include/haproxy/server.h b/include/haproxy/server.h index ad5baef34..71a953b57 100644 --- a/include/haproxy/server.h +++ b/include/haproxy/server.h @@ -207,7 +207,7 @@ static inline void server_index_id(struct proxy *px, struct server *srv) /* increase the number of cumulated streams on the designated server */ static inline void srv_inc_sess_ctr(struct server *s) { - if (s->counters.shared.tg[tgid - 1]) { + if (s->counters.shared.tg && s->counters.shared.tg[tgid - 1]) { _HA_ATOMIC_INC(&s->counters.shared.tg[tgid - 1]->cum_sess); update_freq_ctr(&s->counters.shared.tg[tgid - 1]->sess_per_sec, 1); } @@ -218,7 +218,7 @@ static inline void srv_inc_sess_ctr(struct server *s) /* set the time of last session on the designated server */ static inline void srv_set_sess_last(struct server *s) { - if (s->counters.shared.tg[tgid - 1]) + if (s->counters.shared.tg && s->counters.shared.tg[tgid - 1]) HA_ATOMIC_STORE(&s->counters.shared.tg[tgid - 1]->last_sess, ns_to_sec(now_ns)); } diff --git a/src/backend.c b/src/backend.c index c8adf38a3..3000548c7 100644 --- a/src/backend.c +++ b/src/backend.c @@ -823,7 +823,7 @@ int assign_server(struct stream *s) else if (srv != prev_srv) { if (s->be_tgcounters) _HA_ATOMIC_INC(&s->be_tgcounters->cum_lbconn); - if (srv->counters.shared.tg[tgid - 1]) + if (srv->counters.shared.tg && srv->counters.shared.tg[tgid - 1]) _HA_ATOMIC_INC(&srv->counters.shared.tg[tgid - 1]->cum_lbconn); } stream_set_srv_target(s, srv); @@ -998,12 +998,12 @@ int assign_server_and_queue(struct stream *s) s->txn->flags |= TX_CK_DOWN; } s->flags |= SF_REDISP; - if (prev_srv->counters.shared.tg[tgid - 1]) + if (prev_srv->counters.shared.tg && prev_srv->counters.shared.tg[tgid - 1]) _HA_ATOMIC_INC(&prev_srv->counters.shared.tg[tgid - 1]->redispatches); if (s->be_tgcounters) _HA_ATOMIC_INC(&s->be_tgcounters->redispatches); } else { - if (prev_srv->counters.shared.tg[tgid - 1]) + if (prev_srv->counters.shared.tg && prev_srv->counters.shared.tg[tgid - 1]) _HA_ATOMIC_INC(&prev_srv->counters.shared.tg[tgid - 1]->retries); if (s->be_tgcounters) _HA_ATOMIC_INC(&s->be_tgcounters->retries); diff --git a/src/cache.c b/src/cache.c index 9f83c9da5..92a1fb9be 100644 --- a/src/cache.c +++ b/src/cache.c @@ -2133,11 +2133,11 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p return ACT_RET_CONT; if (px == strm_fe(s)) { - if (px->fe_counters.shared.tg[tgid - 1]) + if (px->fe_counters.shared.tg && px->fe_counters.shared.tg[tgid - 1]) _HA_ATOMIC_INC(&px->fe_counters.shared.tg[tgid - 1]->p.http.cache_lookups); } else { - if (px->be_counters.shared.tg[tgid - 1]) + if (px->be_counters.shared.tg && px->be_counters.shared.tg[tgid - 1]) _HA_ATOMIC_INC(&px->be_counters.shared.tg[tgid - 1]->p.http.cache_lookups); } @@ -2226,11 +2226,11 @@ 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)) { - if (px->fe_counters.shared.tg[tgid - 1]) + if (px->fe_counters.shared.tg && px->fe_counters.shared.tg[tgid - 1]) _HA_ATOMIC_INC(&px->fe_counters.shared.tg[tgid - 1]->p.http.cache_hits); } else { - if (px->be_counters.shared.tg[tgid - 1]) + if (px->be_counters.shared.tg && px->be_counters.shared.tg[tgid - 1]) _HA_ATOMIC_INC(&px->be_counters.shared.tg[tgid - 1]->p.http.cache_hits); } return ACT_RET_CONT; diff --git a/src/check.c b/src/check.c index 002ee88c7..7835ddce2 100644 --- a/src/check.c +++ b/src/check.c @@ -513,7 +513,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)) { - if (s->counters.shared.tg[tgid - 1]) + if (s->counters.shared.tg && s->counters.shared.tg[tgid - 1]) _HA_ATOMIC_INC(&s->counters.shared.tg[tgid - 1]->failed_checks); report = 1; check->health--; @@ -741,7 +741,7 @@ void __health_adjust(struct server *s, short status) HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock); HA_ATOMIC_STORE(&s->consecutive_errors, 0); - if (s->counters.shared.tg[tgid - 1]) + if (s->counters.shared.tg && s->counters.shared.tg[tgid - 1]) _HA_ATOMIC_INC(&s->counters.shared.tg[tgid - 1]->failed_hana); if (s->check.fastinter) { diff --git a/src/cli.c b/src/cli.c index 32365d70a..09494c718 100644 --- a/src/cli.c +++ b/src/cli.c @@ -3372,8 +3372,14 @@ read_again: target_pid = s->pcli_next_pid; /* we can connect now */ s->target = pcli_pid_to_server(target_pid); - if (objt_server(s->target)) - s->sv_tgcounters = __objt_server(s->target)->counters.shared.tg[tgid - 1]; + if (objt_server(s->target)) { + struct server *srv = __objt_server(s->target); + + if (srv->counters.shared.tg) + s->sv_tgcounters = srv->counters.shared.tg[tgid - 1]; + else + s->sv_tgcounters = NULL; + } if (!s->target) goto server_disconnect; diff --git a/src/counters.c b/src/counters.c index 1f6238c37..3e19fec45 100644 --- a/src/counters.c +++ b/src/counters.c @@ -37,7 +37,7 @@ static void _counters_shared_drop(void *counters) if (!shared) return; - while (it < global.nbtgroups && shared->tg[it]) { + while (it < global.nbtgroups && shared->tg && shared->tg[it]) { if (shared->flags & COUNTERS_SHARED_F_LOCAL) { /* memory was allocated using calloc(), simply free it */ free(shared->tg[it]); @@ -53,6 +53,7 @@ static void _counters_shared_drop(void *counters) } it += 1; } + free(shared->tg); } /* release a shared fe counters struct */ @@ -86,6 +87,14 @@ static int _counters_shared_prepare(struct counters_shared *shared, if (!guid->key || !shm_stats_file_hdr) shared->flags |= COUNTERS_SHARED_F_LOCAL; + if (!shared->tg) { + shared->tg = calloc(global.nbtgroups, sizeof(*shared->tg)); + if (!shared->tg) { + memprintf(errmsg, "couldn't allocate memory for shared counters"); + return 0; + } + } + while (it < global.nbtgroups) { if (shared->flags & COUNTERS_SHARED_F_LOCAL) { size_t tg_size; diff --git a/src/http_client.c b/src/http_client.c index bd9023520..64fbc8707 100644 --- a/src/http_client.c +++ b/src/http_client.c @@ -951,8 +951,14 @@ int httpclient_applet_init(struct appctx *appctx) s = appctx_strm(appctx); s->target = target; - if (objt_server(s->target)) - s->sv_tgcounters = __objt_server(s->target)->counters.shared.tg[tgid - 1]; + if (objt_server(s->target)) { + struct server *srv = __objt_server(s->target); + + if (srv->counters.shared.tg) + s->sv_tgcounters = __objt_server(s->target)->counters.shared.tg[tgid - 1]; + else + s->sv_tgcounters = NULL; + } /* set the "timeout server" */ s->scb->ioto = hc->timeout_server; diff --git a/src/listener.c b/src/listener.c index 5e7d556e8..9dd01250f 100644 --- a/src/listener.c +++ b/src/listener.c @@ -1117,7 +1117,7 @@ void listener_accept(struct listener *l) int max = 0; int it; - for (it = 0; (it < global.nbtgroups && p->fe_counters.shared.tg[it]); it++) + for (it = 0; (it < global.nbtgroups && p->fe_counters.shared.tg && p->fe_counters.shared.tg[it]); it++) max += freq_ctr_remain(&p->fe_counters.shared.tg[it]->sess_per_sec, p->fe_sps_lim, 0); if (unlikely(!max)) { diff --git a/src/proxy.c b/src/proxy.c index ced820343..f7c8a6c9e 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -2578,7 +2578,11 @@ int stream_set_backend(struct stream *s, struct proxy *be) return 0; s->be = be; - s->be_tgcounters = be->be_counters.shared.tg[tgid - 1]; + if (be->be_counters.shared.tg) + s->be_tgcounters = be->be_counters.shared.tg[tgid - 1]; + else + s->be_tgcounters = NULL; + HA_ATOMIC_UPDATE_MAX(&be->be_counters.conn_max, HA_ATOMIC_ADD_FETCH(&be->beconn, 1)); proxy_inc_be_ctr(be); diff --git a/src/server.c b/src/server.c index b6109db85..d023e2033 100644 --- a/src/server.c +++ b/src/server.c @@ -7159,7 +7159,7 @@ static void srv_update_status(struct server *s, int type, int cause) } else if (s->cur_state == SRV_ST_STOPPED) { /* server was up and is currently down */ - if (s->counters.shared.tg[tgid - 1]) + if (s->counters.shared.tg && s->counters.shared.tg[tgid - 1]) HA_ATOMIC_INC(&s->counters.shared.tg[tgid - 1]->down_trans); _srv_event_hdl_publish(EVENT_HDL_SUB_SERVER_DOWN, cb_data.common, s); } @@ -7174,7 +7174,7 @@ static void srv_update_status(struct server *s, int type, int cause) } s->last_change = ns_to_sec(now_ns); - if (s->counters.shared.tg[tgid - 1]) + if (s->counters.shared.tg && s->counters.shared.tg[tgid - 1]) HA_ATOMIC_STORE(&s->counters.shared.tg[tgid - 1]->last_state_change, s->last_change); /* publish the state change */ @@ -7195,7 +7195,7 @@ static void srv_update_status(struct server *s, int type, int cause) if (last_change < ns_to_sec(now_ns)) // ignore negative times s->proxy->down_time += ns_to_sec(now_ns) - last_change; s->proxy->last_change = ns_to_sec(now_ns); - if (s->proxy->be_counters.shared.tg[tgid - 1]) + if (s->proxy->be_counters.shared.tg && s->proxy->be_counters.shared.tg[tgid - 1]) HA_ATOMIC_STORE(&s->proxy->be_counters.shared.tg[tgid - 1]->last_state_change, s->proxy->last_change); } } diff --git a/src/server_state.c b/src/server_state.c index 1fa2ffd94..3b728281a 100644 --- a/src/server_state.c +++ b/src/server_state.c @@ -322,7 +322,7 @@ static void srv_state_srv_update(struct server *srv, int version, char **params) } srv->last_change = ns_to_sec(now_ns) - srv_last_time_change; - if (srv->counters.shared.tg[0]) + if (srv->counters.shared.tg && srv->counters.shared.tg[0]) HA_ATOMIC_STORE(&srv->counters.shared.tg[0]->last_state_change, srv->last_change); srv->check.status = srv_check_status; srv->check.result = srv_check_result; diff --git a/src/session.c b/src/session.c index ba93ac29c..4cef01b67 100644 --- a/src/session.c +++ b/src/session.c @@ -99,8 +99,12 @@ struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type sess->flags = SESS_FL_NONE; sess->src = NULL; sess->dst = NULL; - sess->fe_tgcounters = sess->fe->fe_counters.shared.tg[tgid - 1]; - if (sess->listener && sess->listener->counters) + if (sess->fe->fe_counters.shared.tg) + sess->fe_tgcounters = sess->fe->fe_counters.shared.tg[tgid - 1]; + else + sess->fe_tgcounters = NULL; + + if (sess->listener && sess->listener->counters && sess->listener->counters->shared.tg) sess->li_tgcounters = sess->listener->counters->shared.tg[tgid - 1]; else sess->li_tgcounters = NULL; diff --git a/src/stats-file.c b/src/stats-file.c index 117707e01..73c13a637 100644 --- a/src/stats-file.c +++ b/src/stats-file.c @@ -293,6 +293,9 @@ static int parse_stat_line(struct ist line, if (!(px->cap & PR_CAP_FE)) return 0; /* silently ignored fe/be mismatch */ + if (!px->fe_counters.shared.tg) + return 0; + base_off_shared = (char *)px->fe_counters.shared.tg[0]; if (!base_off_shared) return 0; // not allocated @@ -305,6 +308,9 @@ static int parse_stat_line(struct ist line, if (!(px->cap & PR_CAP_BE)) return 0; /* silently ignored fe/be mismatch */ + if (!px->be_counters.shared.tg) + return 0; + base_off_shared = (char *)px->be_counters.shared.tg[0]; if (!base_off_shared) return 0; // not allocated @@ -328,6 +334,9 @@ static int parse_stat_line(struct ist line, if (!li->counters) return 0; + if (!li->counters->shared.tg) + return 0; + base_off_shared = (char *)li->counters->shared.tg[0]; if (!base_off_shared) return 0; // not allocated @@ -342,6 +351,9 @@ static int parse_stat_line(struct ist line, goto err; srv = __objt_server(node->obj_type); + if (!srv->counters.shared.tg) + return 0; + base_off_shared = (char *)srv->counters.shared.tg[0]; if (!base_off_shared) return 0; // not allocated @@ -765,8 +777,13 @@ static void shm_stats_file_preload(void) BUG_ON(curr_obj->type != SHM_STATS_FILE_OBJECT_TYPE_FE); li = __objt_listener(node->obj_type); // counters are optional for listeners - if (li->counters) + if (li->counters) { + if (!li->counters->shared.tg) + li->counters->shared.tg = calloc(global.nbtgroups, sizeof(*li->counters->shared.tg)); + if (li->counters->shared.tg == NULL) + goto release; li->counters->shared.tg[obj_tgid - 1] = &curr_obj->data.fe; + } break; } case OBJ_TYPE_SERVER: @@ -775,6 +792,10 @@ static void shm_stats_file_preload(void) BUG_ON(curr_obj->type != SHM_STATS_FILE_OBJECT_TYPE_BE); sv = __objt_server(node->obj_type); + if (!sv->counters.shared.tg) + sv->counters.shared.tg = calloc(global.nbtgroups, sizeof(*sv->counters.shared.tg)); + if (sv->counters.shared.tg == NULL) + goto release; sv->counters.shared.tg[obj_tgid - 1] = &curr_obj->data.be; break; } @@ -783,11 +804,19 @@ static void shm_stats_file_preload(void) struct proxy *px; px = __objt_proxy(node->obj_type); - if (curr_obj->type == SHM_STATS_FILE_OBJECT_TYPE_FE) + if (curr_obj->type == SHM_STATS_FILE_OBJECT_TYPE_FE) { + if (!px->fe_counters.shared.tg) + px->fe_counters.shared.tg = calloc(global.nbtgroups, sizeof(*px->fe_counters.shared.tg)); + if (px->fe_counters.shared.tg == NULL) + goto release; px->fe_counters.shared.tg[obj_tgid - 1] = &curr_obj->data.fe; - else if (curr_obj->type == SHM_STATS_FILE_OBJECT_TYPE_BE) + } else if (curr_obj->type == SHM_STATS_FILE_OBJECT_TYPE_BE) { + if (!px->be_counters.shared.tg) + px->be_counters.shared.tg = calloc(global.nbtgroups, sizeof(*px->be_counters.shared.tg)); + if (px->fe_counters.shared.tg == NULL) + goto release; px->be_counters.shared.tg[obj_tgid - 1] = &curr_obj->data.be; - else + } else goto release; // not supported break; } diff --git a/src/stats-proxy.c b/src/stats-proxy.c index 1e5fcf3a6..03b1999c0 100644 --- a/src/stats-proxy.c +++ b/src/stats-proxy.c @@ -290,7 +290,7 @@ static struct field me_generate_field(const struct stat_col *col, case STATS_PX_CAP_FE: case STATS_PX_CAP_LI: if (col->flags & STAT_COL_FL_SHARED) { - counter = (char *)&((struct fe_counters *)counters)->shared.tg; + counter = ((struct fe_counters *)counters)->shared.tg; offset = col->metric.offset[0]; } else @@ -301,7 +301,7 @@ static struct field me_generate_field(const struct stat_col *col, case STATS_PX_CAP_BE: case STATS_PX_CAP_SRV: if (col->flags & STAT_COL_FL_SHARED) { - counter = (char *)&((struct be_counters *)counters)->shared.tg; + counter = ((struct be_counters *)counters)->shared.tg; offset = col->metric.offset[1]; } else diff --git a/src/stream.c b/src/stream.c index bceeecf56..6daffdd94 100644 --- a/src/stream.c +++ b/src/stream.c @@ -451,7 +451,11 @@ struct stream *stream_new(struct session *sess, struct stconn *sc, struct buffer * when the default backend is assigned. */ s->be = sess->fe; - s->be_tgcounters = sess->fe->be_counters.shared.tg[tgid - 1]; + if (sess->fe->be_counters.shared.tg) + s->be_tgcounters = sess->fe->be_counters.shared.tg[tgid - 1]; + else + s->be_tgcounters = NULL; + s->sv_tgcounters = NULL; // default value s->req_cap = NULL;