mirror of
https://gitlab.nic.cz/knot/knot-dns.git
synced 2026-05-28 04:02:31 -04:00
server: add configuration option for enabling socket affinity
This commit is contained in:
parent
3101a3d488
commit
2f4d05ecd1
10 changed files with 84 additions and 13 deletions
|
|
@ -190,6 +190,7 @@ server:
|
|||
tcp\-remote\-io\-timeout: INT
|
||||
tcp\-max\-clients: INT
|
||||
tcp\-reuseport: BOOL
|
||||
socket\-affinity: BOOL
|
||||
udp\-max\-payload: SIZE
|
||||
udp\-max\-payload\-ipv4: SIZE
|
||||
udp\-max\-payload\-ipv6: SIZE
|
||||
|
|
@ -332,6 +333,16 @@ advisable to use this option on slave servers.
|
|||
Change of this parameter requires restart of the Knot server to take effect.
|
||||
.sp
|
||||
\fIDefault:\fP off
|
||||
.SS socket\-affinity
|
||||
.sp
|
||||
If enabled and if SO_REUSEPORT is available on Linux, all configured network
|
||||
sockets are bound to UDP and TCP workers in order to increase the networking performance.
|
||||
This mode isn\(aqt recommended for setups where the number of network card queues
|
||||
is lower than the number of UDP or TCP workers.
|
||||
.sp
|
||||
Change of this parameter requires restart of the Knot server to take effect.
|
||||
.sp
|
||||
\fIDefault:\fP off
|
||||
.SS tcp\-max\-clients
|
||||
.sp
|
||||
A maximum number of TCP clients connected in parallel, set this below the file
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ General options related to the server.
|
|||
tcp-remote-io-timeout: INT
|
||||
tcp-max-clients: INT
|
||||
tcp-reuseport: BOOL
|
||||
socket-affinity: BOOL
|
||||
udp-max-payload: SIZE
|
||||
udp-max-payload-ipv4: SIZE
|
||||
udp-max-payload-ipv6: SIZE
|
||||
|
|
@ -328,6 +329,20 @@ Change of this parameter requires restart of the Knot server to take effect.
|
|||
|
||||
*Default:* off
|
||||
|
||||
.. _server_socket-affinity:
|
||||
|
||||
socket-affinity
|
||||
---------------
|
||||
|
||||
If enabled and if SO_REUSEPORT is available on Linux, all configured network
|
||||
sockets are bound to UDP and TCP workers in order to increase the networking performance.
|
||||
This mode isn't recommended for setups where the number of network card queues
|
||||
is lower than the number of UDP or TCP workers.
|
||||
|
||||
Change of this parameter requires restart of the Knot server to take effect.
|
||||
|
||||
*Default:* off
|
||||
|
||||
.. _server_tcp-max-clients:
|
||||
|
||||
tcp-max-clients
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -124,6 +124,7 @@ static void init_cache(
|
|||
|
||||
static bool first_init = true;
|
||||
static bool running_tcp_reuseport;
|
||||
static bool running_socket_affinity;
|
||||
static size_t running_udp_threads;
|
||||
static size_t running_tcp_threads;
|
||||
static size_t running_xdp_threads;
|
||||
|
|
@ -131,6 +132,7 @@ static void init_cache(
|
|||
|
||||
if (first_init || reinit_cache) {
|
||||
running_tcp_reuseport = conf_tcp_reuseport(conf);
|
||||
running_socket_affinity = conf_socket_affinity(conf);
|
||||
running_udp_threads = conf_udp_threads(conf);
|
||||
running_tcp_threads = conf_tcp_threads(conf);
|
||||
running_xdp_threads = conf_xdp_threads(conf);
|
||||
|
|
@ -183,6 +185,8 @@ static void init_cache(
|
|||
|
||||
conf->cache.srv_tcp_reuseport = running_tcp_reuseport;
|
||||
|
||||
conf->cache.srv_socket_affinity = running_socket_affinity;
|
||||
|
||||
conf->cache.srv_udp_threads = running_udp_threads;
|
||||
|
||||
conf->cache.srv_tcp_threads = running_tcp_threads;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -114,6 +114,7 @@ typedef struct {
|
|||
int srv_tcp_io_timeout;
|
||||
int srv_tcp_remote_io_timeout;
|
||||
bool srv_tcp_reuseport;
|
||||
bool srv_socket_affinity;
|
||||
size_t srv_udp_threads;
|
||||
size_t srv_tcp_threads;
|
||||
size_t srv_xdp_threads;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -1174,6 +1174,14 @@ bool conf_tcp_reuseport_txn(
|
|||
return conf_bool(&val);
|
||||
}
|
||||
|
||||
bool conf_socket_affinity_txn(
|
||||
conf_t *conf,
|
||||
knot_db_txn_t *txn)
|
||||
{
|
||||
conf_val_t val = conf_get_txn(conf, txn, C_SRV, C_SOCKET_AFFINITY);
|
||||
return conf_bool(&val);
|
||||
}
|
||||
|
||||
size_t conf_udp_threads_txn(
|
||||
conf_t *conf,
|
||||
knot_db_txn_t *txn)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -686,6 +686,24 @@ static inline bool conf_tcp_reuseport(
|
|||
return conf_tcp_reuseport_txn(conf, &conf->read_txn);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Gets the configured setting of the socket affinity switch.
|
||||
*
|
||||
* \param[in] conf Configuration.
|
||||
* \param[in] txn Configuration DB transaction.
|
||||
*
|
||||
* \return True if enabled, false otherwise.
|
||||
*/
|
||||
bool conf_socket_affinity_txn(
|
||||
conf_t *conf,
|
||||
knot_db_txn_t *txn
|
||||
);
|
||||
static inline bool conf_socket_affinity(
|
||||
conf_t *conf)
|
||||
{
|
||||
return conf_socket_affinity_txn(conf, &conf->read_txn);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Gets the configured number of UDP threads.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -171,6 +171,7 @@ static const yp_item_t desc_server[] = {
|
|||
{ C_TCP_RMT_IO_TIMEOUT, YP_TINT, YP_VINT = { 0, INT32_MAX, 5000 } },
|
||||
{ C_TCP_MAX_CLIENTS, YP_TINT, YP_VINT = { 0, INT32_MAX, YP_NIL } },
|
||||
{ C_TCP_REUSEPORT, YP_TBOOL, YP_VNONE },
|
||||
{ C_SOCKET_AFFINITY, YP_TBOOL, YP_VNONE },
|
||||
{ C_UDP_MAX_PAYLOAD, YP_TINT, YP_VINT = { KNOT_EDNS_MIN_DNSSEC_PAYLOAD,
|
||||
KNOT_EDNS_MAX_UDP_PAYLOAD,
|
||||
1232, YP_SSIZE } },
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -105,6 +105,7 @@
|
|||
#define C_SERVER "\x06""server"
|
||||
#define C_SIGNING_THREADS "\x0F""signing-threads"
|
||||
#define C_SINGLE_TYPE_SIGNING "\x13""single-type-signing"
|
||||
#define C_SOCKET_AFFINITY "\x0F""socket-affinity"
|
||||
#define C_SRV "\x06""server"
|
||||
#define C_STATS "\x0A""statistics"
|
||||
#define C_STORAGE "\x07""storage"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -307,13 +307,14 @@ static iface_t *server_init_xdp_iface(struct sockaddr_storage *addr, unsigned *t
|
|||
* \param udp_thread_count Number of created UDP workers.
|
||||
* \param tcp_thread_count Number of created TCP workers.
|
||||
* \param tcp_reuseport Indication if reuseport on TCP is enabled.
|
||||
* \param socket_affinity Indication if CBPF should be attached.
|
||||
*
|
||||
* \retval Pointer to a new initialized inteface.
|
||||
* \retval NULL if error.
|
||||
*/
|
||||
static iface_t *server_init_iface(struct sockaddr_storage *addr,
|
||||
int udp_thread_count, int tcp_thread_count,
|
||||
bool tcp_reuseport)
|
||||
bool tcp_reuseport, bool socket_affinity)
|
||||
{
|
||||
iface_t *new_if = calloc(1, sizeof(*new_if));
|
||||
if (new_if == NULL) {
|
||||
|
|
@ -374,7 +375,7 @@ static iface_t *server_init_iface(struct sockaddr_storage *addr,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (udp_bind_flags & NET_BIND_MULTIPLE) {
|
||||
if ((udp_bind_flags & NET_BIND_MULTIPLE) && socket_affinity) {
|
||||
if (!server_attach_reuseport_bpf(sock, udp_socket_count) &&
|
||||
warn_cbpf) {
|
||||
log_warning("cannot ensure optimal CPU locality for UDP");
|
||||
|
|
@ -446,7 +447,7 @@ static iface_t *server_init_iface(struct sockaddr_storage *addr,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (tcp_bind_flags & NET_BIND_MULTIPLE) {
|
||||
if ((tcp_bind_flags & NET_BIND_MULTIPLE) && socket_affinity) {
|
||||
if (!server_attach_reuseport_bpf(sock, tcp_socket_count) &&
|
||||
warn_cbpf) {
|
||||
log_warning("cannot ensure optimal CPU locality for TCP");
|
||||
|
|
@ -475,7 +476,9 @@ static int configure_sockets(conf_t *conf, server_t *s)
|
|||
|
||||
#ifdef ENABLE_REUSEPORT
|
||||
/* Log info if reuseport is used and for what protocols. */
|
||||
log_info("using reuseport for UDP%s", conf->cache.srv_tcp_reuseport ? " and TCP" : "");
|
||||
log_info("using reuseport%s for UDP%s",
|
||||
conf->cache.srv_socket_affinity ? " with socket affinity" : "",
|
||||
conf->cache.srv_tcp_reuseport ? " and TCP" : "");
|
||||
#endif
|
||||
|
||||
/* Update bound interfaces. */
|
||||
|
|
@ -505,6 +508,7 @@ static int configure_sockets(conf_t *conf, server_t *s)
|
|||
unsigned size_udp = s->handlers[IO_UDP].handler.unit->size;
|
||||
unsigned size_tcp = s->handlers[IO_TCP].handler.unit->size;
|
||||
bool tcp_reuseport = conf->cache.srv_tcp_reuseport;
|
||||
bool socket_affinity = conf->cache.srv_socket_affinity;
|
||||
char *rundir = conf_abs_path(&rundir_val, NULL);
|
||||
while (listen_val.code == KNOT_EOK) {
|
||||
struct sockaddr_storage addr = conf_addr(&listen_val, rundir);
|
||||
|
|
@ -513,7 +517,7 @@ static int configure_sockets(conf_t *conf, server_t *s)
|
|||
log_info("binding to interface %s", addr_str);
|
||||
|
||||
iface_t *new_if = server_init_iface(&addr, size_udp, size_tcp,
|
||||
tcp_reuseport);
|
||||
tcp_reuseport, socket_affinity);
|
||||
if (new_if == NULL) {
|
||||
server_deinit_iface_list(newlist, nifs);
|
||||
free(rundir);
|
||||
|
|
@ -861,6 +865,7 @@ static void warn_server_reconfigure(conf_t *conf, server_t *server)
|
|||
const char *msg = "changes of %s require restart to take effect";
|
||||
|
||||
static bool warn_tcp_reuseport = true;
|
||||
static bool warn_socket_affinity = true;
|
||||
static bool warn_udp = true;
|
||||
static bool warn_tcp = true;
|
||||
static bool warn_bg = true;
|
||||
|
|
@ -871,6 +876,11 @@ static void warn_server_reconfigure(conf_t *conf, server_t *server)
|
|||
warn_tcp_reuseport = false;
|
||||
}
|
||||
|
||||
if (warn_socket_affinity && conf->cache.srv_socket_affinity != conf_socket_affinity(conf)) {
|
||||
log_warning(msg, &C_SOCKET_AFFINITY[1]);
|
||||
warn_socket_affinity = false;
|
||||
}
|
||||
|
||||
if (warn_udp && server->handlers[IO_UDP].size != conf_udp_threads(conf)) {
|
||||
log_warning(msg, &C_UDP_WORKERS[1]);
|
||||
warn_udp = false;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -908,6 +908,7 @@ static void test_conf_io_list(void)
|
|||
"server.tcp-remote-io-timeout\n"
|
||||
"server.tcp-max-clients\n"
|
||||
"server.tcp-reuseport\n"
|
||||
"server.socket-affinity\n"
|
||||
"server.udp-workers\n"
|
||||
"server.tcp-workers\n"
|
||||
"server.background-workers\n"
|
||||
|
|
@ -930,6 +931,7 @@ static const yp_item_t desc_server[] = {
|
|||
{ C_TCP_RMT_IO_TIMEOUT, YP_TINT, YP_VNONE },
|
||||
{ C_TCP_MAX_CLIENTS, YP_TINT, YP_VNONE },
|
||||
{ C_TCP_REUSEPORT, YP_TBOOL, YP_VNONE },
|
||||
{ C_SOCKET_AFFINITY, YP_TBOOL, YP_VNONE },
|
||||
{ C_UDP_WORKERS, YP_TINT, YP_VNONE },
|
||||
{ C_TCP_WORKERS, YP_TINT, YP_VNONE },
|
||||
{ C_BG_WORKERS, YP_TINT, YP_VNONE },
|
||||
|
|
|
|||
Loading…
Reference in a new issue