From a2547e15cb05cd3d363d290d20f86b876047c14a Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Thu, 2 Jul 2026 18:49:48 +0200 Subject: [PATCH] MEDIUM: backend: Do not always allow takeover across thread groups When we're running with separate file descriptor tables across thread groups, do not allow connection takeover across thread groups, as the connection would not be usable for that thread, anyway. --- src/backend.c | 19 ++++++++++++++++--- src/fd.c | 2 ++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/backend.c b/src/backend.c index ab1a8d963..1c374676e 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1406,7 +1406,8 @@ check_tgid: if (!found && (global.tune.tg_takeover == FULL_THREADGROUP_TAKEOVER || (global.tune.tg_takeover == RESTRICTED_THREADGROUP_TAKEOVER && - srv->flags & (SRV_F_RHTTP | SRV_F_STRICT_MAXCONN)))) { + srv->flags & (SRV_F_RHTTP | SRV_F_STRICT_MAXCONN))) && + !(global.tune.options & GTUNE_NO_TG_FD_SHARING)) { curtgid = curtgid + 1; if (curtgid == global.nbtgroups + 1) curtgid = 1; @@ -1513,14 +1514,26 @@ static int kill_random_idle_conn(struct server *srv) { struct connection *conn = NULL; + uint base = 0, count = global.nbthread, start = tid; int i; int curtid; /* No idle conn, then there is nothing we can do at this point */ if (srv->curr_idle_conns == 0) return -1; - for (i = 0; i < global.nbthread; i++) { - curtid = (i + tid) % global.nbthread; + + /* + * with per-thread-group fd tables, a connection cannot be taken over + * from a thread of another group, as its fd is only valid in the + * owner group's table, so only consider our own group's threads. + */ + if (global.tune.options & GTUNE_NO_TG_FD_SHARING) { + base = tg->base; + count = tg->count; + start = ti->ltid; + } + for (i = 0; i < count; i++) { + curtid = base + (start + i) % count; if (HA_SPIN_TRYLOCK(IDLE_CONNS_LOCK, &idle_conns[curtid].idle_conns_lock) != 0) continue; diff --git a/src/fd.c b/src/fd.c index 66e256cd6..c1f725029 100644 --- a/src/fd.c +++ b/src/fd.c @@ -552,6 +552,8 @@ int fd_takeover(int fd, void *expected_owner) /* We're taking a connection from a different thread group */ if ((fdtab[fd].refc_tgid & 0x7fff) != tgid) { + BUG_ON(global.tune.options & GTUNE_NO_TG_FD_SHARING); + changing_tgid = 1; old_tgid = fd_tgid(fd); -- 2.47.3