diff --git a/doc/configuration.txt b/doc/configuration.txt index 968c031dc..a5195a1d7 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -4165,8 +4165,11 @@ tune.bufsize.small If however a small buffer is not sufficient, a reallocation is automatically done to switch to a standard size buffer. - For the moment, it is used only by HTTP/3 protocol to emit the response - headers. + For the moment, it is automatically used only by HTTP/3 protocol to emit the + response headers. Otherwise, small buffers support can be enabled for + specific proxies via the "use-small-buffers" option. + + See also: option use-small-buffers tune.comp.maxlevel Sets the maximum compression level. The compression level affects CPU @@ -6066,6 +6069,7 @@ option tcp-smart-connect (*) X - X X option tcpka X X X X option tcplog X X X - option transparent (deprecated) (*) X - X X +option use-small-buffers (*) X - X X persist rdp-cookie X - X X quic-initial X (!) X X - rate-limit sessions X X X - @@ -11905,6 +11909,36 @@ no option transparent (deprecated) "transparent" option of the "bind" keyword. +option use-small-buffers [ queue | l7-retries | check ]* + + Enable support for small buffers for the given categories. + + May be used in the following contexts: tcp, http + + May be used in sections : defaults | frontend | listen | backend + yes | no | yes | yes + + This option can be used to enable the small buffers support at diffent places + to save memory. By default, with no parameter, small buffers are used as far + as possible at all possible places. Otherwise, it is possible to limit it to + following the places: + + - queue: When set, small buffers will be used to store the requests, if + small enough, when the connection is queued. + - l7-retries: When set, small buffers will be used to save the requests + when L7 retries are enabled. + - check: When set, small buffers will be used for the health-checks + requests. + + When enabled, small buffers are used, but only if it is possible. Otherwise, + when data are too large, a regular buffer is automtically used. The size of + small buffers is configurable via the "tune.bufsize.small" global setting. + + If this option has been enabled in a "defaults" section, it can be disabled + in a specific instance by prepending the "no" keyword before it. + + See also: tune.bufsize.small + persist rdp-cookie persist rdp-cookie() Enable RDP cookie-based persistence diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index fbd9e3ca3..07ef037da 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -162,7 +162,11 @@ enum PR_SRV_STATE_FILE { #define PR_O2_EXT_CHK 0x04000000 /* use external command for server health */ #define PR_O2_CHK_ANY 0x06000000 /* Mask to cover any check */ -/* unused : 0x08000000 ... 0x80000000 */ +#define PR_O2_USE_SBUF_QUEUE 0x08000000 /* use small buffer for request when stream are queued*/ +#define PR_O2_USE_SBUF_L7_RETRY 0x10000000 /* use small buffer for request when L7 retires are enabled */ +#define PR_O2_USE_SBUF_CHECK 0x20000000 /* use small buffer for request's healthchecks */ +#define PR_O2_USE_SBUF_ALL 0x38000000 /* all flags for use-large-buffer option */ +/* unused : 0x40000000 ... 0x80000000 */ /* end of proxy->options2 */ /* bits for proxy->options3 */ diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index 76d6b6f91..1b28fbd8e 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -2200,6 +2200,42 @@ stats_error_parsing: err_code |= ERR_ALERT | ERR_FATAL; goto out; } + else if (strcmp(args[1], "use-small-buffers") == 0) { + unsigned int flags = PR_O2_USE_SBUF_ALL; + + if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) { + err_code |= ERR_WARN; + goto out; + } + + if (*(args[2])) { + int cur_arg; + + flags = 0; + for (cur_arg = 2; *(args[cur_arg]); cur_arg++) { + if (strcmp(args[cur_arg], "queue") == 0) + flags |= PR_O2_USE_SBUF_QUEUE; + else if (strcmp(args[cur_arg], "l7-retries") == 0) + flags |= PR_O2_USE_SBUF_L7_RETRY; + else if (strcmp(args[cur_arg], "check") == 0) + flags |= PR_O2_USE_SBUF_CHECK; + else { + ha_alert("parsing [%s:%d] : invalid parameter '%s'. option '%s' expects 'queue', 'l7-retries' or 'check' value.\n", + file, linenum, args[cur_arg], args[1]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + } + } + if (kwm == KWM_STD) { + curproxy->options2 &= ~PR_O2_USE_SBUF_ALL; + curproxy->options2 |= flags; + } + else if (kwm == KWM_NO) { + curproxy->options2 &= ~flags; + } + goto out; + } if (kwm != KWM_STD) { ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n", diff --git a/src/check.c b/src/check.c index f89769e6d..45ada607c 100644 --- a/src/check.c +++ b/src/check.c @@ -1685,7 +1685,8 @@ static int start_checks() */ for (px = proxies_list; px; px = px->next) { for (s = px->srv; s; s = s->next) { - if (s->check.tcpcheck_rules->flags & TCPCHK_RULES_MAY_USE_SBUF) + if ((px->options2 & PR_O2_USE_SBUF_CHECK) && + (s->check.tcpcheck_rules->flags & TCPCHK_RULES_MAY_USE_SBUF)) s->check.state |= CHK_ST_USE_SMALL_BUFF; if (s->check.state & CHK_ST_CONFIGURED) { diff --git a/src/stconn.c b/src/stconn.c index 84ceb0841..9f5575d4f 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -1496,7 +1496,8 @@ int sc_conn_send(struct stconn *sc) if (s->txn->req.msg_state != HTTP_MSG_DONE || b_is_large(&oc->buf)) s->txn->flags &= ~TX_L7_RETRY; else { - if (!htx_copy_to_small_buffer(&s->txn->l7_buffer, &oc->buf)) { + if (!(s->be->options2 & PR_O2_USE_SBUF_L7_RETRY) || + !htx_copy_to_small_buffer(&s->txn->l7_buffer, &oc->buf)) { if (b_alloc(&s->txn->l7_buffer, DB_UNLIKELY) == NULL) s->txn->flags &= ~TX_L7_RETRY; else { diff --git a/src/stream.c b/src/stream.c index 8886763bf..a83a4f68e 100644 --- a/src/stream.c +++ b/src/stream.c @@ -2512,7 +2512,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) if (scb->state == SC_ST_ASS && srv && srv->rdr_len && (s->flags & SF_REDIRECTABLE)) http_perform_server_redirect(s, scb); - if (unlikely(scb->state == SC_ST_QUE)) { + if (unlikely((s->be->options2 & PR_O2_USE_SBUF_QUEUE) && scb->state == SC_ST_QUE)) { struct buffer sbuf = BUF_NULL; if (IS_HTX_STRM(s)) {