mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-20 13:21:29 +02:00
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.
This commit is contained in:
parent
07c10ec2f1
commit
d624aceaef
@ -121,7 +121,13 @@ static int dns_connect_nameserver(struct dns_nameserver *ns)
|
||||
|
||||
/* Add the fd in the fd list and update its parameters */
|
||||
dgram->t.sock.fd = fd;
|
||||
fd_insert(fd, dgram, dgram_fd_handler, tgid, tg->threads_enabled);
|
||||
|
||||
/* let's stick the FD to the initiator thread, this will ensure that
|
||||
* most of the time, a resolver will not try to access its structure
|
||||
* at the same time as a response is processed, and will eliminate
|
||||
* locking contention.
|
||||
*/
|
||||
fd_insert(fd, dgram, dgram_fd_handler, tgid, ti->ltid_bit);
|
||||
fd_want_recv(fd);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user