diff --git a/include/haproxy/counters-t.h b/include/haproxy/counters-t.h index 8c21d9b70..9a45609e2 100644 --- a/include/haproxy/counters-t.h +++ b/include/haproxy/counters-t.h @@ -197,7 +197,7 @@ enum counters_type { }; struct extra_counters { - char *data; /* heap containing counters allocated in a linear fashion */ + char **datap; /* points to pointer to heap containing counters allocated in a linear fashion */ size_t size; /* size of allocated data */ enum counters_type type; /* type of object containing the counters */ }; diff --git a/include/haproxy/counters.h b/include/haproxy/counters.h index a9e6c30ea..f40dd6d84 100644 --- a/include/haproxy/counters.h +++ b/include/haproxy/counters.h @@ -106,16 +106,17 @@ void counters_be_shared_drop(struct be_counters_shared *counters); /* Manipulation of extra_counters, for boot-time registrable modules */ #define EXTRA_COUNTERS_GET(counters, mod) \ (likely(counters) ? \ - ((void *)((counters)->data + (mod)->counters_off[(counters)->type])) : \ + ((void *)(*(counters)->datap + (mod)->counters_off[(counters)->type])) : \ (trash_counters)) -#define EXTRA_COUNTERS_REGISTER(counters, ctype, alloc_failed_label) \ +#define EXTRA_COUNTERS_REGISTER(counters, ctype, alloc_failed_label, storage) \ do { \ typeof(*counters) _ctr; \ _ctr = calloc(1, sizeof(*_ctr)); \ if (!_ctr) \ goto alloc_failed_label; \ _ctr->type = (ctype); \ + _ctr->datap = (storage); \ *(counters) = _ctr; \ } while (0) @@ -129,22 +130,22 @@ void counters_be_shared_drop(struct be_counters_shared *counters); #define EXTRA_COUNTERS_ALLOC(counters, alloc_failed_label) \ do { \ typeof(counters) _ctr = (counters); \ - _ctr->data = malloc((_ctr)->size); \ - if (!_ctr->data) \ + *_ctr->datap = malloc((_ctr)->size); \ + if (!*_ctr->datap) \ goto alloc_failed_label; \ } while (0) #define EXTRA_COUNTERS_INIT(counters, mod, init_counters, init_counters_size) \ do { \ typeof(counters) _ctr = (counters); \ - memcpy(_ctr->data + mod->counters_off[_ctr->type], \ + memcpy(*_ctr->datap + mod->counters_off[_ctr->type], \ (init_counters), (init_counters_size)); \ } while (0) #define EXTRA_COUNTERS_FREE(counters) \ do { \ if (counters) { \ - free((counters)->data); \ + ha_free((counters)->datap);\ free(counters); \ } \ } while (0) diff --git a/include/haproxy/dns-t.h b/include/haproxy/dns-t.h index 344b085d9..10175cfdf 100644 --- a/include/haproxy/dns-t.h +++ b/include/haproxy/dns-t.h @@ -152,6 +152,7 @@ struct dns_nameserver { struct dns_stream_server *stream; /* used for tcp dns */ EXTRA_COUNTERS(extra_counters); + char *extra_counters_storage; /* storage used for extra_counters above */ struct dns_counters *counters; struct list list; /* nameserver chained list */ diff --git a/include/haproxy/listener-t.h b/include/haproxy/listener-t.h index cc08a2243..a6990cbd9 100644 --- a/include/haproxy/listener-t.h +++ b/include/haproxy/listener-t.h @@ -263,6 +263,7 @@ struct listener { struct li_per_thread *per_thr; /* per-thread fields (one per thread in the group) */ + char *extra_counters_storage; /* storage for extra_counters */ EXTRA_COUNTERS(extra_counters); }; diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index c71bde526..18b25ce81 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -305,6 +305,8 @@ struct error_snapshot { struct proxy_per_tgroup { struct queue queue; struct lbprm_per_tgrp lbprm; + char *extra_counters_fe_storage; /* storage for extra_counters_fe */ + char *extra_counters_be_storage; /* storage for extra_counters_be */ } THREAD_ALIGNED(); struct proxy { diff --git a/include/haproxy/server-t.h b/include/haproxy/server-t.h index 325361767..c8f318c5c 100644 --- a/include/haproxy/server-t.h +++ b/include/haproxy/server-t.h @@ -286,6 +286,7 @@ struct srv_per_tgroup { struct queue queue; /* pending connections */ struct server *server; /* pointer to the corresponding server */ struct eb32_node lb_node; /* node used for tree-based load balancing */ + char *extra_counters_storage; /* storage for extra_counters */ struct server *next_full; /* next server in the temporary full list */ unsigned int last_other_tgrp_served; /* Last other tgrp we dequeued from */ unsigned int self_served; /* Number of connection we dequeued from our own queue */ diff --git a/include/haproxy/stats.h b/include/haproxy/stats.h index acebd27b8..a02bcb6dd 100644 --- a/include/haproxy/stats.h +++ b/include/haproxy/stats.h @@ -168,7 +168,7 @@ static inline enum stats_domain_px_cap stats_px_get_cap(uint32_t domain) } int stats_allocate_proxy_counters_internal(struct extra_counters **counters, - int type, int px_cap); + int type, int px_cap, char **storage); int stats_allocate_proxy_counters(struct proxy *px); void stats_register_module(struct stats_module *m); diff --git a/src/proxy.c b/src/proxy.c index 49aa4a2ec..ed6a92c1c 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -4914,7 +4914,8 @@ static int cli_parse_add_backend(char **args, char *payload, struct appctx *appc if (!stats_allocate_proxy_counters_internal(&px->extra_counters_be, COUNTERS_BE, - STATS_PX_CAP_BE)) { + STATS_PX_CAP_BE, + &px->per_tgrp->extra_counters_be_storage)) { memprintf(&msg, "failed to allocate extra counters"); goto err; } diff --git a/src/resolvers.c b/src/resolvers.c index 6cbb4448a..4a62427ac 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -2906,7 +2906,7 @@ int resolv_allocate_counters(struct list *stat_modules) list_for_each_entry(resolvers, &sec_resolvers, list) { list_for_each_entry(ns, &resolvers->nameservers, list) { EXTRA_COUNTERS_REGISTER(&ns->extra_counters, COUNTERS_RSLV, - alloc_failed); + alloc_failed, &ns->extra_counters_storage); list_for_each_entry(mod, stat_modules, list) { EXTRA_COUNTERS_ADD(mod, @@ -2918,12 +2918,12 @@ int resolv_allocate_counters(struct list *stat_modules) EXTRA_COUNTERS_ALLOC(ns->extra_counters, alloc_failed); list_for_each_entry(mod, stat_modules, list) { - memcpy(ns->extra_counters->data + mod->counters_off[ns->extra_counters->type], + memcpy(*ns->extra_counters->datap + mod->counters_off[ns->extra_counters->type], mod->counters, mod->counters_size); /* Store the ns counters pointer */ if (strcmp(mod->name, "resolvers") == 0) { - ns->counters = (struct dns_counters *)ns->extra_counters->data + mod->counters_off[COUNTERS_RSLV]; + ns->counters = (struct dns_counters *)(*ns->extra_counters->datap) + mod->counters_off[COUNTERS_RSLV]; ns->counters->id = ns->id; ns->counters->ns_puid = ns->puid; ns->counters->pid = resolvers->id; diff --git a/src/server.c b/src/server.c index 10de4faa3..536f96a36 100644 --- a/src/server.c +++ b/src/server.c @@ -6285,7 +6285,8 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct if (!stats_allocate_proxy_counters_internal(&srv->extra_counters, COUNTERS_SV, - STATS_PX_CAP_SRV)) { + STATS_PX_CAP_SRV, + &srv->per_tgrp->extra_counters_storage)) { ha_alert("failed to allocate extra counters for server.\n"); goto out; } diff --git a/src/stats.c b/src/stats.c index ad2a11d83..c8347bf67 100644 --- a/src/stats.c +++ b/src/stats.c @@ -1094,11 +1094,11 @@ static void cli_io_handler_release_dump_stat_file(struct appctx *appctx) } int stats_allocate_proxy_counters_internal(struct extra_counters **counters, - int type, int px_cap) + int type, int px_cap, char **storage) { struct stats_module *mod; - EXTRA_COUNTERS_REGISTER(counters, type, alloc_failed); + EXTRA_COUNTERS_REGISTER(counters, type, alloc_failed, storage); list_for_each_entry(mod, &stats_module_list[STATS_DOMAIN_PROXY], list) { if (!(stats_px_get_cap(mod->domain_flags) & px_cap)) @@ -1133,7 +1133,8 @@ int stats_allocate_proxy_counters(struct proxy *px) if (px->cap & PR_CAP_FE) { if (!stats_allocate_proxy_counters_internal(&px->extra_counters_fe, COUNTERS_FE, - STATS_PX_CAP_FE)) { + STATS_PX_CAP_FE, + &px->per_tgrp->extra_counters_fe_storage)) { return 0; } } @@ -1141,7 +1142,8 @@ int stats_allocate_proxy_counters(struct proxy *px) if (px->cap & PR_CAP_BE) { if (!stats_allocate_proxy_counters_internal(&px->extra_counters_be, COUNTERS_BE, - STATS_PX_CAP_BE)) { + STATS_PX_CAP_BE, + &px->per_tgrp->extra_counters_be_storage)) { return 0; } } @@ -1149,7 +1151,8 @@ int stats_allocate_proxy_counters(struct proxy *px) for (sv = px->srv; sv; sv = sv->next) { if (!stats_allocate_proxy_counters_internal(&sv->extra_counters, COUNTERS_SV, - STATS_PX_CAP_SRV)) { + STATS_PX_CAP_SRV, + &sv->per_tgrp->extra_counters_storage)) { return 0; } } @@ -1157,7 +1160,8 @@ int stats_allocate_proxy_counters(struct proxy *px) list_for_each_entry(li, &px->conf.listeners, by_fe) { if (!stats_allocate_proxy_counters_internal(&li->extra_counters, COUNTERS_LI, - STATS_PX_CAP_LI)) { + STATS_PX_CAP_LI, + &li->extra_counters_storage)) { return 0; } }