]> git.ipfire.org Git - thirdparty/haproxy.git/commit
MEDIUM: dns: bind the nameserver sockets to the initiating thread
authorWilly Tarreau <w@1wt.eu>
Wed, 10 Sep 2025 14:37:40 +0000 (16:37 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 10 Sep 2025 14:48:09 +0000 (16:48 +0200)
commitd624aceaef5ddf09cc8869990ffb4033ad93a452
treedac253d55d00cd5b6ca59fd2def4b00fd2e2e9a9
parent07c10ec2f124801b1d58454f13c331c5a0b77b0e
MEDIUM: dns: bind the nameserver sockets to the initiating thread

There's still a big architectural limitation in the dns/resolvers code
regarding threads: resolvers run as a task that is scheduled to run
anywhere, and each NS dgram socket is bound to any thread of the same
thread group as the initiating thread. This becomes a big problem when
dealing with multiple nameservers because responses arrive on any thread,
start by locking the resolvers section, and other threads dealing with
responses are just stuck waiting for the lock to disappear. This means
that most of the time is exclusively spent causing contention. The
process_resolvers() function also also suffers from this contention
but apparently less often.

It turns out that the nameserver sockets are created during emission
of the first packet, triggered from the resolvers task. The present
patch exploits this to stick all sockets to the calling thread instead
of any thread. This way there is no longer any contention between
multiple nameservers of a same resolvers section. Tests with a section
having 10 name servers showed that the CPU usage dropped from 38 to
about 10%, or almost by a factor of 4.

Note that TCP resolvers do not offer this possibility because the
tasks that manage the applets are created earlier to run anywhere
during config parsing. This might possibly be refined later, e.g.
by changing the task's affinity when it first runs.

The change was kept fairly minimal to permit a backport once enough
testing is conducted on it. It could address a significant part of
the trouble reported by Felipe in GH issue #3101.
src/dns.c