Since the following patch, protocol API to update a connection TID
affinity has been extended.
commit
1a43b9f32c71267e3cb514aa70a13c75adb20742
MINOR: proto: extend connection thread rebind API
The single callback set_affinity has been splitted in 3 different
functions which are called at different stages during listener_accept(),
depending on accept queue push success or not. However, the naming was
rendered confusing by the usage of function prefix 1 and 2.
Rename proto callback related to TID affinity update and use the
following names :
* bind_tid_prep
* bind_tid_commit
* bind_tid_reset
This commit should probably be backported at least up to 3.0 with the
above patch. This is because the fix was recently backported and it
would allow to keep changes minimal between the two versions. It could
even be backported up to 2.8 if there is no major conflict.
int rhttp_suspend_listener(struct listener *l);
struct connection *rhttp_accept_conn(struct listener *l, int *status);
void rhttp_unbind_receiver(struct listener *l);
-int rhttp_set_affinity(struct connection *conn, int new_tid);
+int rhttp_bind_tid_prep(struct connection *conn, int new_tid);
int rhttp_accepting_conn(const struct receiver *rx);
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 */
- /* functions related to thread affinity update */
+ /* API for thread affinity notification from listener_accept()
+ * [ tid selected ] -->
+ * <bind_tid_prep> --> [ acc queue push ] == OK --> <bind_tid_commit>
+ * == ERR -> <bind_tid_reset>
+ */
/* prepare rebind connection on a new thread, may fail */
- int (*set_affinity1)(struct connection *conn, int new_tid);
+ int (*bind_tid_prep)(struct connection *conn, int new_tid);
/* complete connection thread rebinding, no error possible */
- void (*set_affinity2)(struct connection *conn);
+ void (*bind_tid_commit)(struct connection *conn);
/* cancel connection thread rebinding */
- void (*reset_affinity)(struct connection *conn);
+ void (*bind_tid_reset)(struct connection *conn);
/* functions acting on the receiver */
int (*rx_suspend)(struct receiver *rx); /* temporarily suspend this receiver for a soft restart */
*/
void listener_accept(struct listener *l)
{
- void (*li_set_affinity2)(struct connection *) __maybe_unused;
+ void (*bind_tid_commit)(struct connection *) __maybe_unused;
struct connection *cli_conn;
struct proxy *p;
unsigned int max_accept;
int ret;
p = l->bind_conf->frontend;
- li_set_affinity2 = l->rx.proto ? l->rx.proto->set_affinity2 : NULL;
+ bind_tid_commit = l->rx.proto ? l->rx.proto->bind_tid_commit : NULL;
/* if l->bind_conf->maxaccept is -1, then max_accept is UINT_MAX. It is
* not really illimited, but it is probably enough.
* reservation in the target ring.
*/
- if (l->rx.proto && l->rx.proto->set_affinity1) {
- if (l->rx.proto->set_affinity1(cli_conn, t)) {
+ if (l->rx.proto && l->rx.proto->bind_tid_prep) {
+ if (l->rx.proto->bind_tid_prep(cli_conn, t)) {
/* Failed migration, stay on the same thread. */
goto local_accept;
}
* when processing this loop.
*/
ring = &accept_queue_rings[t];
- if (accept_queue_push_mp(ring, cli_conn, li_set_affinity2)) {
+ if (accept_queue_push_mp(ring, cli_conn, bind_tid_commit)) {
_HA_ATOMIC_INC(&activity[t].accq_pushed);
tasklet_wakeup(ring->tasklet);
*/
_HA_ATOMIC_INC(&activity[t].accq_full);
- if (l->rx.proto && l->rx.proto->reset_affinity)
- l->rx.proto->reset_affinity(cli_conn);
+ if (l->rx.proto && l->rx.proto->bind_tid_reset)
+ l->rx.proto->bind_tid_reset(cli_conn);
}
#endif // USE_THREAD
static int quic_connect_server(struct connection *conn, int flags);
static void quic_enable_listener(struct listener *listener);
static void quic_disable_listener(struct listener *listener);
-static int quic_set_affinity1(struct connection *conn, int new_tid);
-static void quic_set_affinity2(struct connection *conn);
-static void quic_reset_affinity(struct connection *conn);
+static int quic_bind_tid_prep(struct connection *conn, int new_tid);
+static void quic_bind_tid_commit(struct connection *conn);
+static void quic_bind_tid_reset(struct connection *conn);
/* Note: must not be declared <const> as its list will be overwritten */
struct protocol proto_quic4 = {
.get_src = quic_sock_get_src,
.get_dst = quic_sock_get_dst,
.connect = quic_connect_server,
- .set_affinity1 = quic_set_affinity1,
- .set_affinity2 = quic_set_affinity2,
- .reset_affinity = quic_reset_affinity,
+ .bind_tid_prep = quic_bind_tid_prep,
+ .bind_tid_commit = quic_bind_tid_commit,
+ .bind_tid_reset = quic_bind_tid_reset,
/* binding layer */
.rx_suspend = udp_suspend_receiver,
.get_src = quic_sock_get_src,
.get_dst = quic_sock_get_dst,
.connect = quic_connect_server,
- .set_affinity1 = quic_set_affinity1,
- .set_affinity2 = quic_set_affinity2,
- .reset_affinity = quic_reset_affinity,
+ .bind_tid_prep = quic_bind_tid_prep,
+ .bind_tid_commit = quic_bind_tid_commit,
+ .bind_tid_reset = quic_bind_tid_reset,
/* binding layer */
.rx_suspend = udp_suspend_receiver,
* target is a listener, and the caller is responsible for guaranteeing that
* the listener assigned to the connection is bound to the requested thread.
*/
-static int quic_set_affinity1(struct connection *conn, int new_tid)
+static int quic_bind_tid_prep(struct connection *conn, int new_tid)
{
struct quic_conn *qc = conn->handle.qc;
return qc_set_tid_affinity1(qc, new_tid);
}
-static void quic_set_affinity2(struct connection *conn)
+static void quic_bind_tid_commit(struct connection *conn)
{
struct quic_conn *qc = conn->handle.qc;
qc_set_tid_affinity2(qc, objt_listener(conn->target));
}
-static void quic_reset_affinity(struct connection *conn)
+static void quic_bind_tid_reset(struct connection *conn)
{
struct quic_conn *qc = conn->handle.qc;
qc_reset_tid_affinity(qc);
.unbind = rhttp_unbind_receiver,
.resume = default_resume_listener,
.accept_conn = rhttp_accept_conn,
- .set_affinity1 = rhttp_set_affinity,
+ .bind_tid_prep = rhttp_bind_tid_prep,
/* address family */
.fam = &proto_fam_rhttp,
l->rx.flags &= ~RX_F_BOUND;
}
-int rhttp_set_affinity(struct connection *conn, int new_tid)
+int rhttp_bind_tid_prep(struct connection *conn, int new_tid)
{
/* Explicitly disable connection thread migration on accept. Indeed,
* it's unsafe to move a connection with its FD to another thread. Note