MEDIUM: stick-table: set the track-sc limit at boottime via tune.stick-counters
The number of stick-counter entries usable by track-sc rules is currently
set at build time. There is no good value for this since the vast majority
of users don't need any, most need only a few and rare users need more.
Adding more counters for everyone increases memory and CPU usages for no
reason.
This patch moves the per-session and per-stream arrays to a pool of a size
defined at boot time. This way it becomes possible to set the number of
entries at boot time via a new global setting "tune.stick-counters" that
sets the limit for the whole process. When not set, the MAX_SESS_STR_CTR
value still applies, or 3 if not set, as before.
It is also possible to lower the value to 0 to save a bit of memory if
not used at all.
Note that a few low-level sample-fetch functions had to be protected due
to the ability to use sample-fetches in the global section to set some
variables.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index c5e6d2a..6d1c2d8 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1158,6 +1158,7 @@
- tune.sched.low-latency
- tune.sndbuf.client
- tune.sndbuf.server
+ - tune.stick-counters
- tune.ssl.cachesize
- tune.ssl.capture-buffer-size
- tune.ssl.capture-cipherlist-size (deprecated)
@@ -3305,6 +3306,21 @@
dynamically is expensive, they are cached. The default cache size is set to
1000 entries.
+tune.stick-counters <number>
+ Sets the number of stick-counters that may be tracked at the same time by a
+ connection or a request via "track-sc*" actions in "tcp-request" or
+ "http-request" rules. The defaut value is set at build time by the macro
+ MAX_SESS_STK_CTR, and defaults to 3. With this setting it is possible to
+ change the value and ignore the one passed at build time. Increasing this
+ value may be needed when porting complex configurations to haproxy, but users
+ are warned against the costs: each entry takes 16 bytes per connection and
+ 16 bytes per request, all of which need to be allocated and zeroed for all
+ requests even when not used. As such a value of 10 will inflate the memory
+ consumption per request by 320 bytes and will cause this memory to be erased
+ for each request, which does have measurable CPU impacts. Conversely, when
+ no "track-sc" rules are used, the value may be lowered (0 being valid to
+ entirely disable stick-counters).
+
tune.vars.global-max-size <size>
tune.vars.proc-max-size <size>
tune.vars.reqres-max-size <size>
@@ -7617,9 +7633,10 @@
This enables tracking of sticky counters from current request. These rules do
not stop evaluation and do not change default action. The number of counters
- that may be simultaneously tracked by the same connection is set in
- MAX_SESS_STKCTR at build time (reported in haproxy -vv) which defaults to 3,
- so the track-sc number is between 0 and (MAX_SESS_STKCTR-1). The first
+ that may be simultaneously tracked by the same connection is set by the
+ global "tune.stick-counters" setting, which defaults to MAX_SESS_STKCTR if
+ set at build time (it is reported in haproxy -vv) and which defaults to 3,
+ so the track-sc number is between 0 and (tune.stick-counters-1). The first
"track-sc0" rule executed enables tracking of the counters of the specified
table as the first set. The first "track-sc1" rule executed enables tracking
of the counters of the specified table as the second set. The first
@@ -18924,12 +18941,12 @@
the incoming connection. For retrieving a value from a sticky counters, the
counter number can be explicitly set as 0, 1, or 2 using the pre-defined
"sc0_", "sc1_", or "sc2_" prefix. These three pre-defined prefixes can only be
-used if MAX_SESS_STKCTR value does not exceed 3, otherwise the counter number
-can be specified as the first integer argument when using the "sc_" prefix.
-Starting from "sc_0" to "sc_N" where N is (MAX_SESS_STKCTR-1). An optional
-table may be specified with the "sc*" form, in which case the currently
-tracked key will be looked up into this alternate table instead of the table
-currently being tracked.
+used if the global "tune.stick-counters" value does not exceed 3, otherwise the
+counter number can be specified as the first integer argument when using the
+"sc_" prefix starting from "sc_0" to "sc_N" where N is (tune.stick-counters-1).
+An optional table may be specified with the "sc*" form, in which case the
+currently tracked key will be looked up into this alternate table instead of
+the table currently being tracked.
bc_dst : ip
This is the destination ip address of the connection on the server side,
diff --git a/include/haproxy/global-t.h b/include/haproxy/global-t.h
index 11f4b2c..92827c6 100644
--- a/include/haproxy/global-t.h
+++ b/include/haproxy/global-t.h
@@ -162,6 +162,7 @@
int pool_high_count; /* max number of opened fd before we start killing idle connections when creating new connections */
size_t pool_cache_size; /* per-thread cache size per pool (defaults to CONFIG_HAP_POOL_CACHE_SIZE) */
unsigned short idle_timer; /* how long before an empty buffer is considered idle (ms) */
+ int nb_stk_ctr; /* number of stick counters, defaults to MAX_SESS_STKCTR */
#ifdef USE_QUIC
unsigned int quic_backend_max_idle_timeout;
unsigned int quic_frontend_max_idle_timeout;
diff --git a/include/haproxy/session-t.h b/include/haproxy/session-t.h
index e7a9899..46023f0 100644
--- a/include/haproxy/session-t.h
+++ b/include/haproxy/session-t.h
@@ -50,7 +50,7 @@
enum obj_type *origin; /* the connection / applet which initiated this session */
struct timeval accept_date; /* date of the session's accept() in user date */
struct timeval tv_accept; /* date of the session's accept() in internal date (monotonic) */
- struct stkctr stkctr[MAX_SESS_STKCTR]; /* stick counters for tcp-connection */
+ struct stkctr *stkctr; /* stick counters for tcp-connection */
struct vars vars; /* list of variables for the session scope. */
struct task *task; /* handshake timeout processing */
long t_handshake; /* handshake duration, -1 = not completed */
diff --git a/include/haproxy/session.h b/include/haproxy/session.h
index 13152cf..38335e4 100644
--- a/include/haproxy/session.h
+++ b/include/haproxy/session.h
@@ -50,7 +50,10 @@
int i;
struct stksess *ts;
- for (i = 0; i < MAX_SESS_STKCTR; i++) {
+ if (unlikely(!sess->stkctr)) // pool not allocated yet
+ return;
+
+ for (i = 0; i < global.tune.nb_stk_ctr; i++) {
struct stkctr *stkctr = &sess->stkctr[i];
ts = stkctr_entry(stkctr);
@@ -80,7 +83,10 @@
{
int i;
+ if (unlikely(!sess->stkctr)) // pool not allocated yet
+ return;
+
- for (i = 0; i < MAX_SESS_STKCTR; i++)
+ for (i = 0; i < global.tune.nb_stk_ctr; i++)
stkctr_inc_http_req_ctr(&sess->stkctr[i]);
}
@@ -94,7 +100,10 @@
{
int i;
- for (i = 0; i < MAX_SESS_STKCTR; i++)
+ if (unlikely(!sess->stkctr)) // pool not allocated yet
+ return;
+
+ for (i = 0; i < global.tune.nb_stk_ctr; i++)
stkctr_inc_http_err_ctr(&sess->stkctr[i]);
}
@@ -107,7 +116,10 @@
{
int i;
- for (i = 0; i < MAX_SESS_STKCTR; i++)
+ if (unlikely(!sess->stkctr)) // pool not allocated yet
+ return;
+
+ for (i = 0; i < global.tune.nb_stk_ctr; i++)
stkctr_inc_http_fail_ctr(&sess->stkctr[i]);
}
diff --git a/include/haproxy/stick_table.h b/include/haproxy/stick_table.h
index 196aabb..cbec137 100644
--- a/include/haproxy/stick_table.h
+++ b/include/haproxy/stick_table.h
@@ -32,6 +32,7 @@
#include <haproxy/ticks.h>
extern struct stktable *stktables_list;
+extern struct pool_head *pool_head_stk_ctr;
extern struct stktable_type stktable_types[];
#define stktable_data_size(type) (sizeof(((union stktable_data*)0)->type))
diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h
index 1ec40f5..fe85217 100644
--- a/include/haproxy/stream-t.h
+++ b/include/haproxy/stream-t.h
@@ -245,7 +245,7 @@
struct stktable *table;
} store[8]; /* tracked stickiness values to store */
- struct stkctr stkctr[MAX_SESS_STKCTR]; /* content-aware stick counters */
+ struct stkctr *stkctr; /* content-aware stick counters */
struct strm_flt strm_flt; /* current state of filters active on this stream */
diff --git a/include/haproxy/stream.h b/include/haproxy/stream.h
index 06716ae..ac2158d 100644
--- a/include/haproxy/stream.h
+++ b/include/haproxy/stream.h
@@ -116,7 +116,10 @@
int i;
struct stksess *ts;
- for (i = 0; i < MAX_SESS_STKCTR; i++) {
+ if (unlikely(!s->stkctr)) // pool not allocated yet
+ return;
+
+ for (i = 0; i < global.tune.nb_stk_ctr; i++) {
ts = stkctr_entry(&s->stkctr[i]);
if (!ts)
continue;
@@ -152,7 +155,10 @@
void *ptr;
int i;
+ if (unlikely(!s->stkctr)) // pool not allocated yet
+ return;
+
- for (i = 0; i < MAX_SESS_STKCTR; i++) {
+ for (i = 0; i < global.tune.nb_stk_ctr; i++) {
ts = stkctr_entry(&s->stkctr[i]);
if (!ts)
continue;
@@ -231,7 +237,10 @@
{
int i;
+ if (unlikely(!s->stkctr)) // pool not allocated yet
+ return;
+
- for (i = 0; i < MAX_SESS_STKCTR; i++) {
+ for (i = 0; i < global.tune.nb_stk_ctr; i++) {
if (!stkctr_inc_http_req_ctr(&s->stkctr[i]))
stkctr_inc_http_req_ctr(&s->sess->stkctr[i]);
}
@@ -244,7 +253,10 @@
{
int i;
- for (i = 0; i < MAX_SESS_STKCTR; i++) {
+ if (unlikely(!s->stkctr)) // pool not allocated yet
+ return;
+
+ for (i = 0; i < global.tune.nb_stk_ctr; i++) {
if (!stkctr_entry(&s->stkctr[i]) || !(stkctr_flags(&s->stkctr[i]) & STKCTR_TRACK_BACKEND))
continue;
@@ -262,7 +274,10 @@
{
int i;
+ if (unlikely(!s->stkctr)) // pool not allocated yet
+ return;
+
- for (i = 0; i < MAX_SESS_STKCTR; i++) {
+ for (i = 0; i < global.tune.nb_stk_ctr; i++) {
if (!stkctr_inc_http_err_ctr(&s->stkctr[i]))
stkctr_inc_http_err_ctr(&s->sess->stkctr[i]);
}
@@ -277,7 +292,10 @@
{
int i;
+ if (unlikely(!s->stkctr)) // pool not allocated yet
+ return;
+
- for (i = 0; i < MAX_SESS_STKCTR; i++) {
+ for (i = 0; i < global.tune.nb_stk_ctr; i++) {
if (!stkctr_inc_http_fail_ctr(&s->stkctr[i]))
stkctr_inc_http_fail_ctr(&s->sess->stkctr[i]);
}
diff --git a/src/cfgparse.c b/src/cfgparse.c
index ac98a95..6f2d93a 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1564,9 +1564,13 @@
return -1;
}
- if (num >= MAX_SESS_STKCTR) {
- memprintf(errmsg, "%u track-sc number exceeding "
- "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
+ if (num >= global.tune.nb_stk_ctr) {
+ if (!global.tune.nb_stk_ctr)
+ memprintf(errmsg, "%u track-sc number not usable, stick-counters "
+ "are disabled by tune.stick-counters", num);
+ else
+ memprintf(errmsg, "%u track-sc number exceeding "
+ "%d (tune.stick-counters-1) value", num, global.tune.nb_stk_ctr - 1);
return -1;
}
diff --git a/src/haproxy.c b/src/haproxy.c
index c454c80..5f345f9 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -204,6 +204,7 @@
#else
.idle_timer = 1000, /* 1 second */
#endif
+ .nb_stk_ctr = MAX_SESS_STKCTR,
#ifdef USE_QUIC
.quic_backend_max_idle_timeout = QUIC_TP_DFLT_BACK_MAX_IDLE_TIMEOUT,
.quic_frontend_max_idle_timeout = QUIC_TP_DFLT_FRONT_MAX_IDLE_TIMEOUT,
diff --git a/src/session.c b/src/session.c
index 3cbacc7..5c868ae 100644
--- a/src/session.c
+++ b/src/session.c
@@ -46,7 +46,13 @@
sess->origin = origin;
sess->accept_date = date; /* user-visible date for logging */
sess->tv_accept = now; /* corrected date for internal use */
- memset(sess->stkctr, 0, sizeof(sess->stkctr));
+ sess->stkctr = NULL;
+ if (pool_head_stk_ctr) {
+ sess->stkctr = pool_alloc(pool_head_stk_ctr);
+ if (!sess->stkctr)
+ goto out_fail_alloc;
+ memset(sess->stkctr, 0, sizeof(sess->stkctr[0]) * global.tune.nb_stk_ctr);
+ }
vars_init_head(&sess->vars, SCOPE_SESS);
sess->task = NULL;
sess->t_handshake = -1; /* handshake not done yet */
@@ -60,6 +66,9 @@
sess->dst = NULL;
}
return sess;
+ out_fail_alloc:
+ pool_free(pool_head_session, sess);
+ return NULL;
}
void session_free(struct session *sess)
@@ -70,6 +79,7 @@
if (sess->listener)
listener_release(sess->listener);
session_store_counters(sess);
+ pool_free(pool_head_stk_ctr, sess->stkctr);
vars_prune_per_sess(&sess->vars);
conn = objt_conn(sess->origin);
if (conn != NULL && conn->mux)
@@ -116,7 +126,7 @@
proxy_inc_fe_sess_ctr(sess->listener, sess->fe);
- for (i = 0; i < MAX_SESS_STKCTR; i++) {
+ for (i = 0; i < global.tune.nb_stk_ctr; i++) {
stkctr = &sess->stkctr[i];
if (!stkctr_entry(stkctr))
continue;
diff --git a/src/stick_table.c b/src/stick_table.c
index 3533ec0..6a86111 100644
--- a/src/stick_table.c
+++ b/src/stick_table.c
@@ -50,7 +50,7 @@
/* structure used to return a table key built from a sample */
static THREAD_LOCAL struct stktable_key static_table_key;
static int (*smp_fetch_src)(const struct arg *, struct sample *, const char *, void *);
-
+struct pool_head *pool_head_stk_ctr __read_mostly = NULL;
struct stktable *stktables_list;
struct eb_root stktable_by_name = EB_ROOT;
@@ -2456,14 +2456,16 @@
struct session *sess, struct stream *s, int flags)
{
struct stksess *ts;
- struct stkctr *stkctr;
+ struct stkctr *stkctr = NULL;
unsigned int period = 0;
/* Extract the stksess, return OK if no stksess available. */
- if (s)
+ if (s && s->stkctr)
stkctr = &s->stkctr[rule->arg.gpc.sc];
- else
+ else if (sess->stkctr)
stkctr = &sess->stkctr[rule->arg.gpc.sc];
+ else
+ return ACT_RET_CONT;
ts = stkctr_entry(stkctr);
if (ts) {
@@ -2522,6 +2524,11 @@
const char *cmd_name = args[*arg-1];
char *error;
+ if (!global.tune.nb_stk_ctr) {
+ memprintf(err, "Cannot use '%s', stick-counters are disabled via tune.stick-counters", args[*arg-1]);
+ return ACT_RET_PRS_ERR;
+ }
+
cmd_name += strlen("sc-inc-gpc");
if (*cmd_name == '(') {
cmd_name++; /* skip the '(' */
@@ -2538,9 +2545,9 @@
return ACT_RET_PRS_ERR;
}
- if (rule->arg.gpc.sc >= MAX_SESS_STKCTR) {
- memprintf(err, "invalid stick table track ID '%s'. The max allowed ID is %d",
- args[*arg-1], MAX_SESS_STKCTR-1);
+ if (rule->arg.gpc.sc >= global.tune.nb_stk_ctr) {
+ memprintf(err, "invalid stick table track ID '%s'. The max allowed ID is %d (tune.stick-counters)",
+ args[*arg-1], global.tune.nb_stk_ctr-1);
return ACT_RET_PRS_ERR;
}
}
@@ -2566,9 +2573,9 @@
return ACT_RET_PRS_ERR;
}
- if (rule->arg.gpc.sc >= MAX_SESS_STKCTR) {
- memprintf(err, "invalid stick table track ID. The max allowed ID is %d",
- MAX_SESS_STKCTR-1);
+ if (rule->arg.gpc.sc >= global.tune.nb_stk_ctr) {
+ memprintf(err, "invalid stick table track ID. The max allowed ID is %d (tune.stick-counters)",
+ global.tune.nb_stk_ctr-1);
return ACT_RET_PRS_ERR;
}
}
@@ -2599,16 +2606,18 @@
{
void *ptr;
struct stksess *ts;
- struct stkctr *stkctr;
+ struct stkctr *stkctr = NULL;
unsigned int value = 0;
struct sample *smp;
int smp_opt_dir;
/* Extract the stksess, return OK if no stksess available. */
- if (s)
+ if (s && s->stkctr)
stkctr = &s->stkctr[rule->arg.gpt.sc];
- else
+ else if (sess->stkctr)
stkctr = &sess->stkctr[rule->arg.gpt.sc];
+ else
+ return ACT_RET_CONT;
ts = stkctr_entry(stkctr);
if (!ts)
@@ -2663,16 +2672,18 @@
{
void *ptr;
struct stksess *ts;
- struct stkctr *stkctr;
+ struct stkctr *stkctr = NULL;
unsigned int value = 0;
struct sample *smp;
int smp_opt_dir;
/* Extract the stksess, return OK if no stksess available. */
- if (s)
+ if (s && s->stkctr)
stkctr = &s->stkctr[rule->arg.gpt.sc];
- else
+ else if (sess->stkctr)
stkctr = &sess->stkctr[rule->arg.gpt.sc];
+ else
+ return ACT_RET_CONT;
ts = stkctr_entry(stkctr);
if (!ts)
@@ -2741,6 +2752,11 @@
char *error;
int smp_val;
+ if (!global.tune.nb_stk_ctr) {
+ memprintf(err, "Cannot use '%s', stick-counters are disabled via tune.stick-counters", args[*arg-1]);
+ return ACT_RET_PRS_ERR;
+ }
+
cmd_name += strlen("sc-set-gpt");
if (*cmd_name == '(') {
cmd_name++; /* skip the '(' */
@@ -2757,9 +2773,9 @@
return ACT_RET_PRS_ERR;
}
- if (rule->arg.gpt.sc >= MAX_SESS_STKCTR) {
+ if (rule->arg.gpt.sc >= global.tune.nb_stk_ctr) {
memprintf(err, "invalid stick table track ID '%s'. The max allowed ID is %d",
- args[*arg-1], MAX_SESS_STKCTR-1);
+ args[*arg-1], global.tune.nb_stk_ctr-1);
return ACT_RET_PRS_ERR;
}
}
@@ -2783,9 +2799,9 @@
return ACT_RET_PRS_ERR;
}
- if (rule->arg.gpt.sc >= MAX_SESS_STKCTR) {
+ if (rule->arg.gpt.sc >= global.tune.nb_stk_ctr) {
memprintf(err, "invalid stick table track ID '%s'. The max allowed ID is %d",
- args[*arg-1], MAX_SESS_STKCTR-1);
+ args[*arg-1], global.tune.nb_stk_ctr-1);
return ACT_RET_PRS_ERR;
}
}
@@ -2914,15 +2930,19 @@
* the sc[0-9]_ form, or even higher using sc_(num) if needed.
* args[arg] is the first optional argument. We first lookup the
* ctr form the stream, then from the session if it was not there.
- * But we must be sure the counter does not exceed MAX_SESS_STKCTR.
+ * But we must be sure the counter does not exceed global.tune.nb_stk_ctr.
*/
- if (num >= MAX_SESS_STKCTR)
+ if (num >= global.tune.nb_stk_ctr)
return NULL;
- if (strm)
+ stkptr = NULL;
+ if (strm && strm->stkctr)
stkptr = &strm->stkctr[num];
- if (!strm || !stkctr_entry(stkptr)) {
- stkptr = &sess->stkctr[num];
+ if (!strm || !stkptr || !stkctr_entry(stkptr)) {
+ if (sess->stkctr)
+ stkptr = &sess->stkctr[num];
+ else
+ return NULL;
if (!stkctr_entry(stkptr))
return NULL;
}
@@ -4990,6 +5010,45 @@
}
}
+static int stk_parse_stick_counters(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
+{
+ char *error;
+ int counters;
+
+ counters = strtol(args[1], &error, 10);
+ if (*error != 0) {
+ memprintf(err, "%s: '%s' is an invalid number", args[0], args[1]);
+ return -1;
+ }
+
+ if (counters < 0) {
+ memprintf(err, "%s: the number of stick-counters may not be negative (was %d)", args[0], counters);
+ return -1;
+ }
+
+ global.tune.nb_stk_ctr = counters;
+ return 0;
+}
+
+/* This function creates the stk_ctr pools after the configuration parsing. It
+ * returns 0 on success otherwise ERR_*. If nb_stk_ctr is 0, the pool remains
+ * NULL.
+ */
+static int stkt_create_stk_ctr_pool(void)
+{
+ if (!global.tune.nb_stk_ctr)
+ return 0;
+
+ pool_head_stk_ctr = create_pool("stk_ctr", sizeof(*((struct session*)0)->stkctr) * global.tune.nb_stk_ctr, MEM_F_SHARED);
+ if (!pool_head_stk_ctr) {
+ ha_alert("out of memory while creating the stick-counters pool.\n");
+ return ERR_ABORT;
+ }
+ return 0;
+}
+
static void stkt_late_init(void)
{
struct sample_fetch *f;
@@ -4997,6 +5056,7 @@
f = find_sample_fetch("src", strlen("src"));
if (f)
smp_fetch_src = f->process;
+ hap_register_post_check(stkt_create_stk_ctr_pool);
}
INITCALL0(STG_INIT, stkt_late_init);
@@ -5273,3 +5333,10 @@
}};
INITCALL1(STG_REGISTER, sample_register_convs, &sample_conv_kws);
+
+static struct cfg_kw_list cfg_kws = {{ },{
+ { CFG_GLOBAL, "tune.stick-counters", stk_parse_stick_counters },
+ { /* END */ }
+}};
+
+INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
diff --git a/src/stream.c b/src/stream.c
index 006c229..04b4081 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -388,13 +388,20 @@
s->last_rule_file = NULL;
s->last_rule_line = 0;
- /* Copy SC counters for the stream. We don't touch refcounts because
- * any reference we have is inherited from the session. Since the stream
- * doesn't exist without the session, the session's existence guarantees
- * we don't lose the entry. During the store operation, the stream won't
- * touch these ones.
- */
- memcpy(s->stkctr, sess->stkctr, sizeof(s->stkctr));
+ s->stkctr = NULL;
+ if (pool_head_stk_ctr) {
+ s->stkctr = pool_alloc(pool_head_stk_ctr);
+ if (!s->stkctr)
+ goto out_fail_alloc;
+
+ /* Copy SC counters for the stream. We don't touch refcounts because
+ * any reference we have is inherited from the session. Since the stream
+ * doesn't exist without the session, the session's existence guarantees
+ * we don't lose the entry. During the store operation, the stream won't
+ * touch these ones.
+ */
+ memcpy(s->stkctr, sess->stkctr, sizeof(s->stkctr[0]) * global.tune.nb_stk_ctr);
+ }
s->sess = sess;
@@ -582,6 +589,8 @@
out_fail_attach_scf:
task_destroy(t);
out_fail_alloc:
+ if (s)
+ pool_free(pool_head_stk_ctr, s->stkctr);
pool_free(pool_head_stream, s);
DBG_TRACE_DEVEL("leaving on error", STRM_EV_STRM_NEW|STRM_EV_STRM_ERR);
return NULL;
@@ -701,6 +710,7 @@
vars_prune(&s->vars_reqres, s->sess, s);
stream_store_counters(s);
+ pool_free(pool_head_stk_ctr, s->stkctr);
list_for_each_entry_safe(bref, back, &s->back_refs, users) {
/* we have to unlink all watchers. We must not relink them if
@@ -797,7 +807,7 @@
if (sess->listener && sess->listener->counters)
_HA_ATOMIC_ADD(&sess->listener->counters->bytes_in, bytes);
- for (i = 0; i < MAX_SESS_STKCTR; i++) {
+ for (i = 0; i < global.tune.nb_stk_ctr; i++) {
if (!stkctr_inc_bytes_in_ctr(&s->stkctr[i], bytes))
stkctr_inc_bytes_in_ctr(&sess->stkctr[i], bytes);
}
@@ -815,7 +825,7 @@
if (sess->listener && sess->listener->counters)
_HA_ATOMIC_ADD(&sess->listener->counters->bytes_out, bytes);
- for (i = 0; i < MAX_SESS_STKCTR; i++) {
+ for (i = 0; i < global.tune.nb_stk_ctr; i++) {
if (!stkctr_inc_bytes_out_ctr(&s->stkctr[i], bytes))
stkctr_inc_bytes_out_ctr(&sess->stkctr[i], bytes);
}
diff --git a/src/tcp_rules.c b/src/tcp_rules.c
index e649794..6465e6e 100644
--- a/src/tcp_rules.c
+++ b/src/tcp_rules.c
@@ -1058,7 +1058,7 @@
memprintf(err,
"'%s %s' expects 'accept', 'reject', 'capture', 'expect-proxy', 'expect-netscaler-cip', 'track-sc0' ... 'track-sc%d', %s "
"in %s '%s' (got '%s').%s%s%s\n",
- args[0], args[1], MAX_SESS_STKCTR-1,
+ args[0], args[1], global.tune.nb_stk_ctr-1,
trash.area, proxy_type_str(curpx),
curpx->id, args[arg],
best ? " Did you mean '" : "",