MINOR: quic: finalize affinity change as soon as possible

During accept, a quic-conn is rebind to a new thread. This process is
done in two times :
* first on the original thread via qc_set_tid_affinity()
* then on the newly assigned thread via qc_finalize_affinity_rebind()

Most quic_conn operations (I/O tasklet, task and quic_conn FD socket
read) are reactivated ony after the second step. However, there is a
possibility that datagrams are handled before it via quic_dgram_parse()
when using listener sockets. This does not seem to cause any issue but
this may cause unexpected behavior in the future.

To simplify this, qc_finalize_affinity_rebind() will be called both by
qc_xprt_start() and quic_dgram_parse(). Only one invocation will be
performed thanks to the new flag QUIC_FL_CONN_AFFINITY_CHANGED.

This should be backported up to 2.7.
This commit is contained in:
Amaury Denoyelle 2023-04-26 17:15:37 +02:00
parent a57ab0fabe
commit d6646dddcc
3 changed files with 11 additions and 1 deletions

View File

@ -628,6 +628,7 @@ enum qc_mux_state {
#define QUIC_FL_CONN_RETRANS_NEEDED (1U << 7)
#define QUIC_FL_CONN_RETRANS_OLD_DATA (1U << 8) /* retransmission in progress for probing with already sent data */
#define QUIC_FL_CONN_TLS_ALERT (1U << 9)
#define QUIC_FL_CONN_AFFINITY_CHANGED (1U << 10) /* qc_finalize_affinity_rebind() must be called to finalize affinity rebind */
/* gap here */
#define QUIC_FL_CONN_HALF_OPEN_CNT_DECREMENTED (1U << 11) /* The half-open connection counter was decremented */
#define QUIC_FL_CONN_HANDSHAKE_SPEED_UP (1U << 12) /* Handshake speeding up was done */

View File

@ -8277,6 +8277,9 @@ int quic_dgram_parse(struct quic_dgram *dgram, struct quic_conn *from_qc,
dgram->qc = qc;
}
if (qc->flags & QUIC_FL_CONN_AFFINITY_CHANGED)
qc_finalize_affinity_rebind(qc);
if (qc_rx_check_closing(qc, pkt)) {
/* Skip the entire datagram. */
pkt->len = end - pos;
@ -8541,6 +8544,7 @@ int qc_set_tid_affinity(struct quic_conn *qc, uint new_tid, struct listener *new
/* Rebinding is considered done when CID points to the new thread. No
* access should be done to quic-conn instance after it.
*/
qc->flags |= QUIC_FL_CONN_AFFINITY_CHANGED;
HA_ATOMIC_STORE(&conn_id->tid, new_tid);
qc = NULL;
@ -8561,6 +8565,10 @@ void qc_finalize_affinity_rebind(struct quic_conn *qc)
{
TRACE_ENTER(QUIC_EV_CONN_SET_AFFINITY, qc);
/* This function must not be called twice after an affinity rebind. */
BUG_ON(!(qc->flags & QUIC_FL_CONN_AFFINITY_CHANGED));
qc->flags &= ~QUIC_FL_CONN_AFFINITY_CHANGED;
/* Reactivate FD polling if connection socket is active. */
qc_want_recv(qc);

View File

@ -132,7 +132,8 @@ static int qc_xprt_start(struct connection *conn, void *ctx)
qc = conn->handle.qc;
TRACE_ENTER(QUIC_EV_CONN_NEW, qc);
qc_finalize_affinity_rebind(qc);
if (qc->flags & QUIC_FL_CONN_AFFINITY_CHANGED)
qc_finalize_affinity_rebind(qc);
/* mux-quic can now be considered ready. */
qc->mux_state = QC_MUX_READY;