]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: protocol: define new callback set_affinity
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 5 Apr 2023 16:16:28 +0000 (18:16 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 18 Apr 2023 14:54:52 +0000 (16:54 +0200)
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.

include/haproxy/protocol-t.h
src/listener.c

index b0765cf87255b5c05d5d6836f2bee035016d7eda..e49a239ceb0f04a36e7196380769bbad7e87b27a 100644 (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 */
index 5fe714ba58ac1f6a8ae0d6c463d47040914cff24..07c7f92ea99bf5254efbbd7ef500eb61895bdf7b 100644 (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