diff --git a/include/haproxy/quic_conn.h b/include/haproxy/quic_conn.h index 3764dceb9..bfd66c470 100644 --- a/include/haproxy/quic_conn.h +++ b/include/haproxy/quic_conn.h @@ -700,7 +700,7 @@ static inline void quic_handle_stopping(void) } } -int qc_set_tid_affinity(struct quic_conn *qc, uint tid); +int qc_set_tid_affinity(struct quic_conn *qc, uint new_tid, struct listener *new_li); void qc_finalize_affinity_rebind(struct quic_conn *qc); #endif /* USE_QUIC */ diff --git a/src/proto_quic.c b/src/proto_quic.c index 8c263772d..76583298e 100644 --- a/src/proto_quic.c +++ b/src/proto_quic.c @@ -707,10 +707,14 @@ static void quic_disable_listener(struct listener *l) fd_stop_recv(l->rx.fd); } +/* change the connection's thread to . For frontend connections, the + * 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_affinity(struct connection *conn, int new_tid) { struct quic_conn *qc = conn->handle.qc; - return qc_set_tid_affinity(qc, new_tid); + return qc_set_tid_affinity(qc, new_tid, objt_listener(conn->target)); } static int quic_alloc_dghdlrs(void) diff --git a/src/quic_conn.c b/src/quic_conn.c index 314c978c4..b474e7209 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -8391,12 +8391,14 @@ int qc_notify_send(struct quic_conn *qc) } /* Move a QUIC connection and its resources from the current thread to the - * new one . After this call, the connection cannot be dereferenced - * anymore on the current thread. + * new one optionally in association with (since it may need + * to change when migrating to a thread from a different group, otherwise leave + * it NULL). After this call, the connection cannot be dereferenced anymore on + * the current thread. * * Returns 0 on success else non-zero. */ -int qc_set_tid_affinity(struct quic_conn *qc, uint new_tid) +int qc_set_tid_affinity(struct quic_conn *qc, uint new_tid, struct listener *new_li) { struct task *t1 = NULL, *t2 = NULL; struct tasklet *t3 = NULL; @@ -8457,6 +8459,13 @@ int qc_set_tid_affinity(struct quic_conn *qc, uint new_tid) node = eb64_first(&qc->cids); BUG_ON(!node || eb64_next(node)); /* One and only one CID must be present before affinity rebind. */ conn_id = eb64_entry(node, struct quic_connection_id, seq_num); + + /* At this point no connection was accounted for yet on this + * listener so it's OK to just swap the pointer. + */ + if (new_li && new_li != qc->li) + qc->li = new_li; + /* Rebinding is considered done when CID points to the new thread. No * access should be done to quic-conn instance after it. */