From: Olivier Houchard Date: Thu, 2 Jul 2026 16:49:48 +0000 (+0200) Subject: MEDIUM: backend: Do not always allow takeover across thread groups X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=a2547e15cb05cd3d363d290d20f86b876047c14a;p=thirdparty%2Fhaproxy.git 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. --- 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);