Commit Graph

13059 Commits

Author SHA1 Message Date
Ilya Shipitsin
c9dfee43f3 BUILD: ssl: use SSL_CTRL_GET_RAW_CIPHERLIST instead of OpenSSL versions
let us use SSL_CTRL_GET_RAW_CIPHERLIST for feature detection instead
of versions

[wla: SSL_CTRL_GET_RAW_CIPHERLIST was introduced by OpenSSL commit
94a209 along with SSL_CIPHER_find. It was removed in boringSSL.]
Signed-off-by: William Lallemand <wlallemand@haproxy.org>
2020-11-03 09:24:43 +01:00
Willy Tarreau
b706a3b4e1 CLEANUP: pattern: remove unused entry "tree" in pattern.val
This one might have disappeared since patterns were reworked, but the
entry was not removed from the structure, let's do it now.
2020-11-02 11:32:05 +01:00
Willy Tarreau
bd703e5650 [RELEASE] Released version 2.3-dev9
Released version 2.3-dev9 with the following main changes :
    - CLEANUP: http_ana: remove unused assignation of `att_beg`
    - BUG/MEDIUM: ssl: OCSP must work with BoringSSL
    - BUG/MINOR: log: fix memory leak on logsrv parse error
    - BUG/MINOR: log: fix risk of null deref on error path
    - BUILD: ssl: more elegant OpenSSL early data support check
    - CI: github actions: update h2spec to 2.6.0
    - BUG/MINOR: cache: Check the return value of http_replace_res_status
    - MINOR: cache: Store the "Last-Modified" date in the cache_entry
    - MINOR: cache: Process the If-Modified-Since header in conditional requests
    - MINOR: cache: Create res.cache_hit and res.cache_name sample fetches
    - MINOR: mux-h2: register a stats module
    - MINOR: mux-h2: add counters instance to h2c
    - MINOR: mux-h2: add stats for received frame types
    - MINOR: mux-h2: report detected error on stats
    - MINOR: mux-h2: count open connections/streams on stats
    - BUG/MINOR: server: fix srv downtime calcul on starting
    - BUG/MINOR: server: fix down_time report for stats
    - BUG/MINOR: lua: initialize sample before using it
    - MINOR: cache: Add Expires header value parsing
    - MINOR: ist: Add a case insensitive istmatch function
    - BUG/MINOR: cache: Manage multiple values in cache-control header value
    - BUG/MINOR: cache: Inverted variables in http_calc_maxage function
    - MINOR: pattern: make pat_ref_append() return the newly added element
    - MINOR: pattern: make pat_ref_add() rely on pat_ref_append()
    - MINOR: pattern: export pat_ref_push()
    - CLEANUP: pattern: use calloc() rather than malloc for structures
    - CLEANUP: pattern: fix spelling/grammatical/copy-paste in comments
2020-10-31 13:17:06 +01:00
Willy Tarreau
a5bbaaf9f4 CLEANUP: pattern: fix spelling/grammatical/copy-paste in comments
The code is horrible to work with because most functions are documented
with misleading comments resulting from many spelling and grammatical
mistakes, and plenty of remains of copy-paste mentioning arguments that
do not exist and return values that are never set. Too many hours wasted
writing non-working code because of assumptions resulting from this,
let's fix this once for all now!
2020-10-31 13:14:10 +01:00
Willy Tarreau
8135d9bc0c CLEANUP: pattern: use calloc() rather than malloc for structures
It's particularly difficult to make sure that the various pattern
structures are properly initialized given that they can be allocated
at multiple places and systematically via malloc() instead of calloc(),
thus not even leaving the possibility of default values. Let's adjust
a few of them.
2020-10-31 13:14:10 +01:00
Willy Tarreau
6bedf151e1 MINOR: pattern: export pat_ref_push()
Strangely this one was marked static inline within the file itself.
Let's export it.
2020-10-31 13:13:48 +01:00
Willy Tarreau
6a1740767c MINOR: pattern: make pat_ref_add() rely on pat_ref_append()
Let's remove unneeded code duplication, both are exactly the same.
2020-10-31 13:13:48 +01:00
Willy Tarreau
f4edb72e0a MINOR: pattern: make pat_ref_append() return the newly added element
It's more convenient to return the element than to return just 0 or 1,
as the next thing we'll want to do is to act on this element! In addition
it was using variable arguments instead of consts, causing some reuse
constraints which were also addressed. This doesn't change its use as
a boolean, hence why call places were not modified.
2020-10-31 13:13:48 +01:00
Remi Tricot-Le Breton
8c2db71326 BUG/MINOR: cache: Inverted variables in http_calc_maxage function
The maxage and smaxage variables were inadvertently assigned the
Cache-Control s-maxage and max-age values respectively when it should
have been the other way around.

This can be backported on all branches after 1.8 (included).
2020-10-30 14:29:29 +01:00
Remi Tricot-Le Breton
40ed97b04b BUG/MINOR: cache: Manage multiple values in cache-control header value
If an HTTP request or response had a "Cache-Control" header that had
multiple comma-separated subparts in its value (like "max-age=1,
no-store" for instance), we did not process the values correctly and
only parsed the first one. That made us store some HTTP responses in the
cache when they were explicitely uncacheable.
This patch replaces the way the values are parsed by an http_find_header
loop that manages every sub part of the value independently.

This patch should be backported to 2.2 and 2.1. The bug also exists on
previous versions but since the sources changed, a new commit will have
to be created.

[wla: This patch requires bb4582c ("MINOR: ist: Add a case insensitive
istmatch function"). Backporting for < 2.1 is not a requirement since it
works well enough for most cases, it was a known limitation of the
implementation of non-htx version too]
2020-10-30 13:28:34 +01:00
Remi Tricot-Le Breton
bb4582cf71 MINOR: ist: Add a case insensitive istmatch function
Add a helper function that checks if a string starts with another string
while ignoring case.
2020-10-30 13:20:21 +01:00
Remi Tricot-Le Breton
a6476114ec MINOR: cache: Add Expires header value parsing
When no Cache-Control max-age or s-maxage information is present in a
cached response, we need to parse the Expires header value (RFC 7234#5.3).
An invalid Expires date value or a date earlier than the reception date
will make the cache_entry stale upon creation.
For now, the Cache-Control and Expires headers are parsed after the
insertion of the response in the cache so even if the parsing of the
Expires results in an already stale entry, the entry will exist in the
cache.
2020-10-30 11:08:38 +01:00
Amaury Denoyelle
bc0af6a199 BUG/MINOR: lua: initialize sample before using it
Memset the sample before using it through hlua_lua2smp. This function is
ORing the smp.flags, so this field need to be cleared before its use.
This was reported by a coverity warning.

Fixes the github issue #929.
This bug can be backported up to 1.8.
2020-10-29 18:52:44 +01:00
Amaury Denoyelle
e6ba7915eb BUG/MINOR: server: fix down_time report for stats
Adjust condition used to report down_time for statistics. There was a
tiny probabilty to have a negative downtime if last_change was superior
to now. If this is the case, return only down_time.

This bug can backported up to 1.8.
2020-10-29 18:52:39 +01:00
Amaury Denoyelle
fe2bf091f6 BUG/MINOR: server: fix srv downtime calcul on starting
When a server is up after a failure, its downtime was reset to 0 on the
statistics. This is due to a wrong condition that causes srv.down_time
to never be set. Fix this by updating down_time each time the server is in
STARTING state.

Fixes the github issue #920.
This bug can be backported up to 1.8.
2020-10-29 18:52:18 +01:00
Amaury Denoyelle
66942c1d4d MINOR: mux-h2: count open connections/streams on stats
Implement as a gauge h2 counters for currently open connections and
streams. The counters are decremented when closing the stream or the
connection.
2020-10-28 08:55:23 +01:00
Amaury Denoyelle
a8879238ce MINOR: mux-h2: report detected error on stats
Implement counters for h2 protocol error on connection or stream level.
Also count the total number of rst_stream and goaway frames sent by the
mux in response to a detected error.
2020-10-28 08:55:19 +01:00
Amaury Denoyelle
2dec1ebec2 MINOR: mux-h2: add stats for received frame types
Implement counters for h2 frame received based on their type for
HEADERS, DATA, SETTINGS, RST_STREAM and GOAWAY.
2020-10-28 08:55:16 +01:00
Amaury Denoyelle
c92697d977 MINOR: mux-h2: add counters instance to h2c
Add pointer to counters as a member for h2c structure. This pointer is
initialized on h2_init function. This is useful to quickly access and
manipulate the counters inside every h2 functions.
2020-10-28 08:55:11 +01:00
Amaury Denoyelle
3238b3f906 MINOR: mux-h2: register a stats module
Use statistics API to register a new stats module generating counters
on h2 module. The counters are attached to frontend/backend instances.
2020-10-28 08:55:07 +01:00
Remi Tricot-Le Breton
bf97121f1c MINOR: cache: Create res.cache_hit and res.cache_name sample fetches
Res.cache_hit sample fetch returns a boolean which is true when the HTTP
response was built out of a cache. The cache's name is returned by the
res.cache_name sample_fetch.

This resolves GitHub issue #900.
2020-10-27 18:25:43 +01:00
Remi Tricot-Le Breton
53161d81b8 MINOR: cache: Process the If-Modified-Since header in conditional requests
If a client sends a conditional request containing an If-Modified-Since
header (and no If-None-Match header), we try to compare the date with
the one stored in the cache entry (coming either from a Last-Modified
head, or a Date header, or corresponding to the first response's
reception time). If the request's date is earlier than the stored one,
we send a "304 Not Modified" response back. Otherwise, the stored is sent
(through a 200 OK response).

This resolves GitHub issue #821.
2020-10-27 18:10:25 +01:00
Remi Tricot Le Breton
27091b4dd0 MINOR: cache: Store the "Last-Modified" date in the cache_entry
In order to manage "If-Modified-Since" requests, we need to keep a
reference time for our cache entries (to which the conditional request's
date will be compared).
This reference is either extracted from the "Last-Modified" header, or
the "Date" header, or the reception time of the response (in decreasing
order of priority).
The date values are converted into seconds since epoch in order to ease
comparisons and to limit storage space.
2020-10-27 18:10:25 +01:00
Tim Duesterhus
e0142340b2 BUG/MINOR: cache: Check the return value of http_replace_res_status
Send the full body if the status `304` cannot be applied. This should be the
most graceful failure.

Specific for 2.3, no backport needed.
2020-10-27 17:01:49 +01:00
Ilya Shipitsin
787c63c816 CI: github actions: update h2spec to 2.6.0 2020-10-27 13:13:23 +01:00
Ilya Shipitsin
b9b84a4b25 BUILD: ssl: more elegant OpenSSL early data support check
BorinSSL pretends to be 1.1.1 version of OpenSSL. It messes some
version based feature presense checks. For example, OpenSSL specific
early data support.

Let us change that feature detction to SSL_READ_EARLY_DATA_SUCCESS
macro check instead of version comparision.
2020-10-27 13:08:32 +01:00
Willy Tarreau
a0133fcf35 BUG/MINOR: log: fix risk of null deref on error path
Previous commit ae32ac74db ("BUG/MINOR: log: fix memory leak on logsrv
parse error") addressed one issue and introduced another one, the logsrv
pointer may also be null at the end of the function so we must test it
before deciding to dereference it.

This should be backported along with the patch above to 2.2.
2020-10-27 10:35:32 +01:00
Willy Tarreau
ae32ac74db BUG/MINOR: log: fix memory leak on logsrv parse error
In case of parsing error on logsrv, we can leave parse_logsrv() without
releasing logsrv->ring_name or smp_rgs. Let's free them on the error path.
This should fix issue #926 detected by Coverity.

The impact is only a tiny leak just before reporting a fatal error, so it
will essentially annoy valgrind.

This can be backported to 2.0 (just drop the ring part).
2020-10-27 09:55:00 +01:00
Emmanuel Hocdet
a73a222a98 BUG/MEDIUM: ssl: OCSP must work with BoringSSL
It's a regression from b3201a3e "BUG/MINOR: disable dynamic OCSP load
with BoringSSL". The origin bug is link to 76b4a12 "BUG/MEDIUM: ssl:
memory leak of ocsp data at SSL_CTX_free()": ssl_sock_free_ocsp()
shoud be in #ifndef OPENSSL_IS_BORINGSSL.
To avoid long #ifdef for small code, the BoringSSL part for ocsp load
is isolated in a simple #ifdef.

This must be backported in 2.2 and 2.1
2020-10-27 09:38:51 +01:00
William Dauchy
5e10e44bce CLEANUP: http_ana: remove unused assignation of att_beg
`att_beg` is assigned to `next` at the end of the `for` loop, but is
assigned to `prev` at the beginning of the loop, which is itself
assigned to `next` after each loop. So it represents a double
assignation for the same value. Also `att_beg` is not used after the end
of the loop.

this is a partial fix for github issue #923, all the others could
probably be marked as intentional to protect future changes.

no backport needed.

Signed-off-by: William Dauchy <wdauchy@gmail.com>
2020-10-26 15:00:09 +01:00
Willy Tarreau
fb1b9e3dec [RELEASE] Released version 2.3-dev8
Released version 2.3-dev8 with the following main changes :
    - MINOR: backend: replace the lbprm lock with an rwlock
    - MINOR: lb/map: use seek lock and read locks where appropriate
    - MINOR: lb/leastconn: only take a read lock in fwlc_get_next_server()
    - MINOR: lb/first: use a read lock in fas_get_next_server()
    - MINOR: lb/chash: use a read lock in chash_get_server_hash()
    - BUG/MINOR: disable dynamic OCSP load with BoringSSL
    - BUILD: ssl: make BoringSSL use its own version numbers
    - CLEANUP: threads: don't register an initcall when not debugging
    - MINOR: threads: change lock_t to an unsigned int
    - CLEANUP: tree-wide: reorder a few structures to plug some holes around locks
    - CLEANUP: task: remove the unused and mishandled global_rqueue_size
    - BUG/MEDIUM: connection: Never cleanup server lists when freeing private conns
    - MEDIUM: config: report that "nbproc" is deprecated
    - BUG/MINOR: listener: close before free in `listener_accept`
    - MINOR: ssl: 'ssl-load-extra-del-ext' removes the certificate extension
    - BUG/MINOR: queue: properly report redistributed connections
    - CONTRIB: tcploop: remove unused local variables in tcp_pause()
    - BUILD: makefile: add entries to build common debugging tools
    - BUG/MEDIUM: server: support changing the slowstart value from state-file
    - MINOR: http: Add `enum etag_type http_get_etag_type(const struct ist)`
    - MINOR: http: Add etag comparison function
    - MEDIUM: cache: Store the ETag information in the cache_entry
    - MEDIUM: cache: Add support for 'If-None-Match' request header
    - REGTEST: cache: Add if-none-match test case
    - CLEANUP: compression: Make use of http_get_etag_type()
    - BUG/MINOR: http-ana: Don't send payload for internal responses to HEAD requests
    - BUG/MAJOR: mux-h2: Don't try to send data if we know it is no longer possible
    - MINOR: threads/debug: only report used lock stats
    - MINOR: threads/debug: only report lock stats for used operations
    - MINOR: proxy; replace the spinlock with an rwlock
    - MINOR: server: read-lock the cookie during srv_set_dyncookie()
    - MINOR: proxy/cli: only take a read lock in "show errors"
    - OPTIM: queue: don't call pendconn_unlink() when the pendconn is not queued
    - MINOR: queue: split __pendconn_unlink() in per-srv and per-prx
    - MINOR: queue: reduce the locked area in pendconn_add()
    - OPTIM: queue: make the nbpend counters atomic
    - OPTIM: queue: decrement the nbpend and totpend counters outside of the lock
    - MINOR: leastconn: take the queue length into account when queuing servers
    - MEDIUM: fwlc: re-enable per-server queuing up to maxqueue
    - Revert "OPTIM: queue: don't call pendconn_unlink() when the pendconn is not queued"
    - MINOR: stats: support the "up" output modifier for "show stat"
    - MINOR: stats: also support a "no-maint" show stat modifier
    - MINOR: stats: indicate the number of servers in a backend's status
    - MEDIUM: ssl: ssl-load-extra-del-ext work only with .crt
    - REGTEST: ssl: test "set ssl cert" with separate key / crt
    - DOC: management: apply the "show stat" modifiers to "show stat", not "show info"
    - MINOR: stats: report server's user-configured weight next to effective weight
    - CI: travis-ci: switch to Ubuntu 20.04
    - CONTRIB: release-estimator: Add release estimating tool
    - BUG/MEDIUM: queue: fix unsafe proxy pointer when counting nbpend
    - BUG/MINOR: extcheck: add missing checks on extchk_setenv()
2020-10-24 13:14:31 +02:00
Willy Tarreau
b3250a268b BUG/MINOR: extcheck: add missing checks on extchk_setenv()
Issue #910 reports that we fail to check a few extchk_setenv() in the
child process. These are mostly harmless, but instead of counting on
the external check script to fail the dirty way, better fail cleanly
when detecting the failure.

This could probably be backported to all stable branches.
2020-10-24 13:07:39 +02:00
Willy Tarreau
5472aa50f1 BUG/MEDIUM: queue: fix unsafe proxy pointer when counting nbpend
As reported by Coverity in issue #917, commit 96bca33 ("OPTIM: queue:
decrement the nbpend and totpend counters outside of the lock")
introduced a bug when moving the increments outside of the loop,
because we can't always rely on the pendconn "p" here as it may
be null. We can retrieve the proxy pointer directly from s->proxy
instead. The same is true for pendconn_redistribute(), though the
last "p" pointer there was still valid. This patch fixes both.

No backport is needed, this was introduced just before 2.3-dev8.
2020-10-24 12:57:41 +02:00
Daniel Corbett
e2370307be CONTRIB: release-estimator: Add release estimating tool
This tool monitors the HAProxy stable branches and calculates a proposed
release date for the next minor release based on the bug fixes that are in
the queue.

Print only:
    ./release-estimator.py --print

Send email:
    ./release-estimator.py --send-mail --from-email from@domain.local --to-email to@domain.local

See contrib/release-estimator/README.md for details.
2020-10-24 12:27:17 +02:00
Ilya Shipitsin
b1faf48222 CI: travis-ci: switch to Ubuntu 20.04
we were blocked by https://github.com/vtest/VTest/issues/20
issue is resolved, let us update to focal
2020-10-24 11:31:56 +02:00
Willy Tarreau
bd71510024 MINOR: stats: report server's user-configured weight next to effective weight
The "weight" column on the stats page is somewhat confusing when using
slowstart becaue it reports the effective weight, without being really
explicit about it. In some situations the user-configured weight is more
relevant (especially with long slowstarts where it's important to know
if the configured weight is correct).

This adds a new uweight stat which reports a server's user-configured
weight, and in a backend it receives the sum of all servers' uweights.
In addition it adds the mention of "effective" in a few descriptions
for the "weight" column (help and doc).

As a result, the list of servers in a backend is now always scanned
when dumping the stats. But this is not a problem given that these
servers are already scanned anyway and for way heavier processing.
2020-10-23 22:47:30 +02:00
Willy Tarreau
698097b54c DOC: management: apply the "show stat" modifiers to "show stat", not "show info"
By mistake I added the "up" then "maint" output modifiers to the "show info"
block instead of the "show stat" one in the two previous commits 65141ffc4
("MINOR: stats: support the "up" output modifier for "show stat"") and
3e3203670 ("MINOR: stats: also support a "no-maint" show stat modifier").

No backport is needed.
2020-10-23 20:22:33 +02:00
William Lallemand
1ac17682e5 REGTEST: ssl: test "set ssl cert" with separate key / crt
This reg-test tests the "set ssl cert" command the same way the
set_ssl_cert.vtc does, but with separate key/crt files and with the
ssl-load-extra-del-ext.

It introduces new key/.crt files that contains the same pair as the
existing .pem.
2020-10-23 18:41:08 +02:00
William Lallemand
089c13850f MEDIUM: ssl: ssl-load-extra-del-ext work only with .crt
In order to be compatible with the "set ssl cert" command of the CLI,
this patch restrict the ssl-load-extra-del-ext to files with a ".crt"
extension in the configuration.

Related to issue #785.

Should be backported where 8e8581e ("MINOR: ssl: 'ssl-load-extra-del-ext'
removes the certificate extension") was backported.
2020-10-23 18:41:08 +02:00
Willy Tarreau
2fbe6940f4 MINOR: stats: indicate the number of servers in a backend's status
When dumping the stats page (or the CSV output), when many states are
mixed, it's hard to figure the number of up servers. But when showing
only the "up" servers or hiding the "maint" servers, there's no way to
know how many servers are configured, which is problematic when trying
to update server-templates.

What this patch does, for dumps in "up" or "no-maint" modes, is to add
after the backend's "UP" or "DOWN" state "(%d/%d)" indicating the number
of servers seen as UP to the total number of servers in the backend. As
such, seeing "UP (33/39)" immediately tells that there are 6 servers that
are not listed when using "up", or will let the client figure how many
servers are left once deducted the number of non-maintenance ones. It's
not done on default dumps so as not to disturb existing tools, which
already have all the information they need in the dump.
2020-10-23 18:11:30 +02:00
Willy Tarreau
3e32036701 MINOR: stats: also support a "no-maint" show stat modifier
"no-maint" is a bit similar to "up" except that it will only hide
servers that are in maintenance (or disabled in the configuration), and
not those that are enabled but failed a check. One benefit here is to
significantly reduce the output of the "show stat" command when using
large server-templates containing entries that are not yet provisioned.

Note that the prometheus exporter also has such an option which does
the exact same.
2020-10-23 18:11:24 +02:00
Willy Tarreau
65141ffc4f MINOR: stats: support the "up" output modifier for "show stat"
We already had it on the HTTP interface but it was not accessible on the
CLI. It can be very convenient to hide servers which are down, do not
resolve, or are in maintenance.
2020-10-23 18:11:24 +02:00
Willy Tarreau
670119955b Revert "OPTIM: queue: don't call pendconn_unlink() when the pendconn is not queued"
This reverts commit b7ba1d9011. Actually
this test had already been removed in the past by commit fac0f645d
("BUG/MEDIUM: queue: make pendconn_cond_unlink() really thread-safe"),
but the condition to reproduce the bug mentioned there was not clear.

Now after analysis and a certain dose of code cleanup, things start to
appear more obvious. what happens is that if we check the presence of
the node in the tree without taking the lock, we can see the NULL at
the instant the node is being unlinked by another thread in
pendconn_process_next_strm() as part of __pendconn_unlink_prx() or
__pendconn_unlink_srv(). Till now there is no issue except that the
pendconn is not removed from the queue during this operation and that
the task is scheduled to be woken up by pendconn_process_next_strm()
with the stream being added to the list of the server's active
connections by __stream_add_srv_conn(). The first thread finishes
faster and gets back to stream_free() faster than the second one
sets the srv_conn on the stream, so stream_free() skips the s->srv_conn
test and doesn't try to dequeue the freshly queued entry. At the
very least a barrier would be needed there but we can't afford to
free the stream while it's being queued. So there's no other solution
than making sure that either __pendconn_unlink_prx() or
pendconn_cond_unlink() get the entry but never both, which is why the
lock is required around the test. A possible solution would be to set
p->target before unlinking the entry and using it to complete the test.
This would leave no dead period where the pendconn is not seen as
attached.

It is possible, yet extremely difficult, to reproduce this bug, which
was first noticed in bug #880. Running 100 servers with maxconn 1 and
maxqueue 1 on leastconn and a connect timeout of 30ms under 16 threads
with DEBUG_UAF, with a traffic making the backend's queue oscillate
around zero (typically using 250 connections with a local httpterm
server) may rarely manage to trigger a use-after-free.

No backport is needed.
2020-10-23 09:21:55 +02:00
Willy Tarreau
8ae8c48eb0 MEDIUM: fwlc: re-enable per-server queuing up to maxqueue
Leastconn has the nice propery of being able to sort servers by their
current usage. It's really a shame to force all requests into the backend
queue when the algo would be able to also consider their current queue.

In order not to change existing behavior but extend it, this patch allows
leastconn to elect servers which are already full if they have an explicitly
configured maxqueue setting above zero and their queue hasn't reached that
threshold. This will significantly reduce the pressure in the backend queue
when queuing a lot with lots of servers.

A test on 8 threads with 100 servers configured with maxconn 1 jumped
from 165krps to 330krps with maxqueue 15 with this patch.

This partially undoes commit 82cd5c13a ("OPTIM: backend: skip LB when we
know the backend is full") but allows to scale much better even by setting
a single-digit maxqueue value. Some better heuristics could be used to
maintain the behavior of the bypass in the patch above, consisting in
keeping it if it's known that there is no server with a configured
maxqueue in the farm (or in the backend).
2020-10-22 18:30:25 +02:00
Willy Tarreau
8c855f6cff MINOR: leastconn: take the queue length into account when queuing servers
When servers are queued into the leastconn tree, it's important to also
consider their queue length. There could be some servers with lots of
queued requests that we don't want to hammer with extra connections. In
order not to add extra stress to the LB algorithm, we don't update the
value when adding to the queue, only when updating the connection count
(i.e. picking from the queue or releasing a connection). This will be
sufficient to significantly improve the fairness in such situations.
2020-10-22 18:30:18 +02:00
Willy Tarreau
96bca33d75 OPTIM: queue: decrement the nbpend and totpend counters outside of the lock
We don't need to do that inside the lock. However since the operation
used to be done in deep functions, we have to make it resurface closer
to visible parts. It remains reasonably self-contained in queue.c so
that's not that big of a deal. Some places (redistribute) could benefit
from a single operation for all counts at once. Others like
pendconn_process_next_strm() are still called with both locks held but
now it will be possible to change this.
2020-10-22 17:32:28 +02:00
Willy Tarreau
56c1cfb179 OPTIM: queue: make the nbpend counters atomic
Instead of incrementing, decrementing them and updating their max under
the lock, make them atomic and keep them out of the lock as much as
possible. For __pendconn_unlink_* it would be wide to decide to move
these counters outside of the function, inside the callers so that a
single atomic op can be done per counter even for groups of operations.
2020-10-22 17:32:28 +02:00
Willy Tarreau
c7eedf7a5a MINOR: queue: reduce the locked area in pendconn_add()
Similarly to previous changes, we know if we're dealing with a server
or proxy lock so let's directly lock at the finest possible places
there. It's worth noting that a part of the operation consisting in
an increment and update of a max could be done outside of the lock
using atomic ops and a CAS.
2020-10-22 17:32:28 +02:00
Willy Tarreau
3e3ae2524d MINOR: queue: split __pendconn_unlink() in per-srv and per-prx
The function is called with the lock held and does too many tests for
things that are already known from its callers. Let's split it in two
so that its callers call either the per-server or per-proxy function
depending on where the element is (since they had to determine it
prior to taking the lock).
2020-10-22 17:32:28 +02:00
Willy Tarreau
b7ba1d9011 OPTIM: queue: don't call pendconn_unlink() when the pendconn is not queued
On connection error processing, we can see massive storms of calls to
pendconn_cond_unlink() to release a possible place in the queue. For
example, in issue #908, on average half of the threads are caught in
this function via back_try_conn_req() consecutive to a synchronous
error. However we wait until grabbing the lock to know if the pendconn
is effectively in a queue, which is expensive for many cases. We know
the transition may only happen from in-queue to out-of-queue so it's safe
to first run a preliminary check to see if it's worth going further. This
will allow to avoid the cost of locking for most requests. This should
not change anything for those completing correctly as they're already
run through pendconn_free() which doesn't call pendconn_cond_unlink()
unless deemed necessary.
2020-10-22 17:32:28 +02:00