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.
This commit is contained in:
Amaury Denoyelle 2023-04-05 18:16:28 +02:00
parent 987812b190
commit a66e04338e
2 changed files with 8 additions and 0 deletions

View File

@ -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 */

View File

@ -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