]> git.ipfire.org Git - thirdparty/haproxy.git/commit
BUG/MEDIUM: listeners: always pause a listener on out-of-resource condition
authorWilly Tarreau <w@1wt.eu>
Fri, 15 Nov 2019 09:20:07 +0000 (10:20 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 15 Nov 2019 09:34:51 +0000 (10:34 +0100)
commit93604edb652542f4149282438dc6e0548cd4d545
tree75e0d7cbd387df716341f4d96f0a1d7b4ca908a3
parentaf7ea814f9e041a97a9a42992d5980db351f2241
BUG/MEDIUM: listeners: always pause a listener on out-of-resource condition

A corner case was opened in the listener_accept() code by commit 3f0d02bbc2
("MAJOR: listener: do not hold the listener lock in listener_accept()"). The
issue is when one listener (or a group of) managed to eat all the proxy's or
all the process's maxconn, and another listener tries to accept a new socket.
This results in the atomic increment to detect the excess connection count
and immediately abort, without pausing the listener, thus the call is
immediately performed again. This doesn't happen when the test is run on a
single listener because this listener got limited when crossing the limit.
But with 2 or more listeners, we don't have this luxury.

The solution consists in limiting the listener as soon as we have to
decline accepting an incoming connection. This means that the listener
will not be marked full yet if it gets the exact connection count but
this is not a problem in practice since all other listeners will only be
marked full after their first attempt. Thus from now on, a listener is
only full once it has already failed taking an incoming connection.

This bug was definitely responsible for the unreproduceable occasional
reports of high CPU usage showing epoll_wait() returning immediately
without accepting an incoming connection, like in bug #129.

This fix must be backported to 1.9 and 1.8.
src/listener.c