From: Willy Tarreau Date: Sat, 22 Apr 2023 09:38:55 +0000 (+0200) Subject: MINOR: listener: automatically adjust shards based on support for SO_REUSEPORT X-Git-Tag: v2.8-dev8~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c1fbdd6397010690b58786cbb561c9dfdb79e906;p=thirdparty%2Fhaproxy.git MINOR: listener: automatically adjust shards based on support for SO_REUSEPORT Now if multiple shards are explicitly requested, and the listener's protocol doesn't support SO_REUSEPORT, sharding is disabled, which will result in the socket being automatically duped if needed. A warning is emitted when this happens. If "shards by-group" or "shards by-thread" are used, these will automatically be turned down to 1 since we want this to be possible easily using -dR on the command line without having to djust the config. For "by-thread", a diag warning will be emitted to help troubleshoot possible performance issues. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 396fc5f566..d337c886c6 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -15297,6 +15297,14 @@ shards | by-thread | by-group sockets. The load distribution will be a bit less optimal but the contention (especially in the system) will still be lower than with a single socket. + On operating systems that do not support multiple sockets bound to the same + address, "by-thread" and "by-group" will automatically fall back to a single + shard. For "by-group" this is done without any warning since it doesn't + change anything for a single group, and will result in sockets being + duplicated for each group anyway. However, for "by-thread", a diagnostic + warning will be emitted if this happens since the resulting number of + listeners will not be the expected one. + ssl This setting is only available when support for OpenSSL was built in. It enables SSL deciphering on connections instantiated from this listener. A diff --git a/src/listener.c b/src/listener.c index 8a3aa7caf8..45595cc69e 100644 --- a/src/listener.c +++ b/src/listener.c @@ -1668,15 +1668,31 @@ int bind_complete_thread_setup(struct bind_conf *bind_conf, int *err_code) todo = thread_set_count(&bind_conf->thread_set); /* special values: -1 = "by-thread", -2 = "by-group" */ - if (shards == -1) - shards = todo; + if (shards == -1) { + if (li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED) + shards = todo; + else { + if (fe != global.cli_fe) + ha_diag_warning("[%s:%d]: Disabling per-thread sharding for listener in" + " %s '%s' because SO_REUSEPORT is disabled\n", + bind_conf->file, bind_conf->line, proxy_type_str(fe), fe->id); + shards = 1; + } + } else if (shards == -2) - shards = my_popcountl(bind_conf->thread_set.grps); + shards = (li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED) ? my_popcountl(bind_conf->thread_set.grps) : 1; /* no more shards than total threads */ if (shards > todo) shards = todo; + /* We also need to check if an explicit shards count was set and cannot be honored */ + if (shards > 1 && !(li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED)) { + ha_warning("[%s:%d]: Disabling sharding for listener in %s '%s' because SO_REUSEPORT is disabled\n", + bind_conf->file, bind_conf->line, proxy_type_str(fe), fe->id); + shards = 1; + } + shard = done = grp = bit = mask = 0; new_li = li;