From: Amaury Denoyelle Date: Wed, 5 Apr 2023 16:16:28 +0000 (+0200) Subject: MINOR: protocol: define new callback set_affinity X-Git-Tag: v2.8-dev8~108 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a66e04338e2f13e7182e43f4b6964b941e4eb504;p=thirdparty%2Fhaproxy.git MINOR: protocol: define new callback set_affinity Define a new protocol callback set_affinity. This function is used during listener_accept() to notify about a rebind on a new thread just before pushing the connection on the selected thread queue. If the callback fails, accept is done locally. This change will be useful for protocols with state allocated before accept is done. For the moment, only QUIC protocol is concerned. This will allow to rebind the quic_conn to a new thread depending on its load. This should be backported up to 2.7 after a period of observation. --- diff --git a/include/haproxy/protocol-t.h b/include/haproxy/protocol-t.h index b0765cf872..e49a239ceb 100644 --- a/include/haproxy/protocol-t.h +++ b/include/haproxy/protocol-t.h @@ -113,6 +113,7 @@ struct protocol { void (*ignore_events)(struct connection *conn, int event_type); /* unsubscribe from socket events */ int (*get_src)(struct connection *conn, struct sockaddr *, socklen_t); /* retrieve connection's source address; -1=fail */ int (*get_dst)(struct connection *conn, struct sockaddr *, socklen_t); /* retrieve connection's dest address; -1=fail */ + int (*set_affinity)(struct connection *conn, int new_tid); /* functions acting on the receiver */ int (*rx_suspend)(struct receiver *rx); /* temporarily suspend this receiver for a soft restart */ diff --git a/src/listener.c b/src/listener.c index 5fe714ba58..07c7f92ea9 100644 --- a/src/listener.c +++ b/src/listener.c @@ -1194,6 +1194,13 @@ void listener_accept(struct listener *l) t1 += (t2 << 16); } while (unlikely(!_HA_ATOMIC_CAS(&l->thr_idx, &t0, t1))); + if (l->rx.proto && l->rx.proto->set_affinity) { + if (l->rx.proto->set_affinity(cli_conn, base + t)) { + /* Failed migration, stay on the same thread. */ + goto local_accept; + } + } + /* We successfully selected the best thread "t" for this * connection. We use deferred accepts even if it's the * local thread because tests show that it's the best