mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-05 02:49:01 +00:00
haproxy public development tree
resume_listener() can be called from a thread not part of the listener's mask after a curr_conn has gone lower than a proxy's or the process' limit. This results in fd_may_recv() being called unlocked if the listener is bound to only one thread, and quickly locks up. This patch solves this by creating a per-thread work_list dedicated to listeners, and modifying resume_listener() so that it bounces the listener to one of its owning thread's work_list and waking it up. This thread will then call resume_listener() again and will perform the operation on the file descriptor itself. It is important to do it this way so that the listener's state cannot be modified while the listener is being moved, otherwise multiple threads can take conflicting decisions and the listener could be put back into the global queue if the listener was used at the same time. It seems like a slightly simpler approach would be possible if the locked list API would provide the ability to return a locked element. In this case the listener would be immediately requeued in dequeue_all_listeners() without having to go through resume_listener() with its associated lock. This fix must be backported to all versions having the lock-less accept loop, which is as far as 1.8 since deadlock fixes involving this feature had to be backported there. It is expected that the code should not differ too much there. However, previous commit "MINOR: task: introduce work lists" will be needed as well and should not present difficulties either. For 1.8, the commits introducing thread_mask() and LIST_ADDED() will be needed as well, either backporting my_flsl() or switching to my_ffsl() will be OK, and some changes will have to be performed so that the init function is properly called (and maybe the deinit one can be dropped). In order to test for the fix, simply set up a multi-threaded frontend with multiple bind lines each attached to a single thread (reproduced with 16 threads here), set up a very low maxconn value on the frontend, and inject heavy traffic on all listeners in parallel with slightly more connections than the configured limit ( typically +20%) so that it flips very frequently. If the bug is still there, at some point (5-20 seconds) the traffic will go much lower or even stop, either with spinning threads or not. |
||
---|---|---|
.github/ISSUE_TEMPLATE | ||
contrib | ||
doc | ||
ebtree | ||
examples | ||
include | ||
reg-tests | ||
scripts | ||
src | ||
tests | ||
.cirrus.yml | ||
.gitignore | ||
.travis.yml | ||
BRANCHES | ||
CHANGELOG | ||
CONTRIBUTING | ||
INSTALL | ||
LICENSE | ||
MAINTAINERS | ||
Makefile | ||
README | ||
ROADMAP | ||
SUBVERS | ||
VERDATE | ||
VERSION |
The HAProxy documentation has been split into a number of different files for ease of use. Please refer to the following files depending on what you're looking for : - INSTALL for instructions on how to build and install HAProxy - BRANCHES to understand the project's life cycle and what version to use - LICENSE for the project's license - CONTRIBUTING for the process to follow to submit contributions The more detailed documentation is located into the doc/ directory : - doc/intro.txt for a quick introduction on HAProxy - doc/configuration.txt for the configuration's reference manual - doc/lua.txt for the Lua's reference manual - doc/SPOE.txt for how to use the SPOE engine - doc/network-namespaces.txt for how to use network namespaces under Linux - doc/management.txt for the management guide - doc/regression-testing.txt for how to use the regression testing suite - doc/peers.txt for the peers protocol reference - doc/coding-style.txt for how to adopt HAProxy's coding style - doc/internals for developer-specific documentation (not all up to date)