Skip to content

Commit 3d19f3d

Browse files
committed
implement active-ns pacing
1 parent dccd5ae commit 3d19f3d

File tree

6 files changed

+66
-13
lines changed

6 files changed

+66
-13
lines changed

include/haproxy/mux_quic-t.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ struct qcc {
6969
struct quic_fctl fc; /* stream flow control applied on sending */
7070
uint64_t buf_in_flight; /* sum of currently allocated Tx buffer sizes */
7171
struct list frms; /* prepared STREAM frames */
72+
ullong next;
7273
} tx;
7374

7475
uint64_t largest_bidi_r; /* largest remote bidi stream ID opened. */

include/haproxy/quic_conn.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ void quic_set_connection_close(struct quic_conn *qc, const struct quic_err err);
163163
void quic_set_tls_alert(struct quic_conn *qc, int alert);
164164
int quic_set_app_ops(struct quic_conn *qc, const unsigned char *alpn, size_t alpn_len);
165165
int qc_check_dcid(struct quic_conn *qc, unsigned char *dcid, size_t dcid_len);
166-
enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms, int max_pkts);
166+
enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms, int *max_pkts);
167167

168168
void qc_notify_err(struct quic_conn *qc);
169169
int qc_notify_send(struct quic_conn *qc);

include/haproxy/tools.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,4 +1246,7 @@ int backup_env(void);
12461246
int clean_env(void);
12471247
int restore_env(void);
12481248

1249+
void work_gtod(int usec);
1250+
1251+
12491252
#endif /* _HAPROXY_TOOLS_H */

src/mux_quic.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,7 +2087,12 @@ static int qcc_subscribe_send(struct qcc *qcc)
20872087
static int qcc_send_frames(struct qcc *qcc, struct list *frms, int strm_content)
20882088
{
20892089
enum quic_tx_err ret;
2090-
int max_burst = strm_content ? global.tune.quic_frontend_max_tx_burst : 0;
2090+
//int max_burst = strm_content ? global.tune.quic_frontend_max_tx_burst : 0;
2091+
2092+
struct quic_conn *qc = qcc->conn->handle.qc;
2093+
ullong ns_pkts = qc->path->loss.srtt * 1000000 / (qc->path->cwnd / 1200 + 1);
2094+
int max_burst = strm_content ? 4000000 / (ns_pkts + 1) + 1 : 0;
2095+
//int max_burst = 1;
20912096

20922097
TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn);
20932098

@@ -2096,14 +2101,14 @@ static int qcc_send_frames(struct qcc *qcc, struct list *frms, int strm_content)
20962101
return -1;
20972102
}
20982103

2099-
ret = qc_send_mux(qcc->conn->handle.qc, frms, max_burst);
2104+
ret = qc_send_mux(qcc->conn->handle.qc, frms, &max_burst);
21002105
if (ret == QUIC_TX_ERR_FATAL) {
21012106
TRACE_DEVEL("error on sending", QMUX_EV_QCC_SEND, qcc->conn);
21022107
qcc_subscribe_send(qcc);
21032108
goto err;
21042109
}
21052110

2106-
BUG_ON(ret == QUIC_TX_ERR_AGAIN && !max_burst);
2111+
//BUG_ON(ret == QUIC_TX_ERR_AGAIN && !max_burst);
21072112

21082113
/* If there is frames left at this stage, transport layer is blocked.
21092114
* Subscribe on it to retry later.
@@ -2114,6 +2119,10 @@ static int qcc_send_frames(struct qcc *qcc, struct list *frms, int strm_content)
21142119
goto err;
21152120
}
21162121

2122+
BUG_ON(ret == QUIC_TX_ERR_AGAIN && !max_burst);
2123+
qcc->tx.next = now_mono_time() + (qc->path->loss.srtt * 1000000 / (qc->path->cwnd / 1200 + 1)) * max_burst;
2124+
//qcc->tx.next = now_mono_time() + (MAX(qc->path->loss.srtt, 10) * 800000 / (qc->path->cwnd / 1200 + 1)) * max_burst;
2125+
21172126
TRACE_LEAVE(QMUX_EV_QCC_SEND, qcc->conn);
21182127
return ret == QUIC_TX_ERR_AGAIN ? 1 : 0;
21192128

@@ -2266,7 +2275,7 @@ static int qcc_io_send(struct qcc *qcc)
22662275
struct list qcs_failed = LIST_HEAD_INIT(qcs_failed);
22672276
struct qcs *qcs, *qcs_tmp, *first_qcs = NULL;
22682277
uint64_t window_conn = qfctl_rcap(&qcc->tx.fc);
2269-
int ret, total = 0, resent;
2278+
int ret = 0, total = 0, resent;
22702279

22712280
TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn);
22722281

@@ -2376,6 +2385,11 @@ static int qcc_io_send(struct qcc *qcc)
23762385
}
23772386
}
23782387

2388+
if (qcc->tx.next > now_mono_time()) {
2389+
qcc_wakeup_pacing(qcc);
2390+
return 1;
2391+
}
2392+
23792393
/* Retry sending until no frame to send, data rejected or connection
23802394
* flow-control limit reached.
23812395
*/
@@ -2412,6 +2426,9 @@ static int qcc_io_send(struct qcc *qcc)
24122426
sent_done:
24132427
/* Deallocate frames that the transport layer has rejected. */
24142428
if (ret == 1) {
2429+
//struct quic_conn *qc = qcc->conn->handle.qc;
2430+
//qcc->tx.next = now_ns + global.tune.pipesize;
2431+
//qcc->tx.next = now_mono_time() + qc->path->loss.srtt * 1000000 / (qc->path->cwnd / 1200 + 1);
24152432
qcc_wakeup_pacing(qcc);
24162433
}
24172434
else if (!LIST_ISEMPTY(&qcc->tx.frms)) {
@@ -2772,9 +2789,17 @@ static int qcc_purge_sending(struct qcc *qcc)
27722789
{
27732790
int ret;
27742791

2792+
if (qcc->tx.next > now_mono_time()) {
2793+
qcc_wakeup_pacing(qcc);
2794+
return 1;
2795+
}
2796+
27752797
//fprintf(stderr, "%s\n", __func__);
27762798
ret = qcc_send_frames(qcc, &qcc->tx.frms, 1);
27772799
if (ret > 0) {
2800+
//struct quic_conn *qc = qcc->conn->handle.qc;
2801+
//qcc->tx.next = now_ns + global.tune.pipesize;
2802+
//qcc->tx.next = now_mono_time() + qc->path->loss.srtt * 1000000 / (qc->path->cwnd / 1200 + 1);
27782803
qcc_wakeup_pacing(qcc);
27792804
return 1;
27802805
}
@@ -2829,6 +2854,7 @@ static struct task *qcc_timeout_task(struct task *t, void *ctx, unsigned int sta
28292854
int expired = tick_is_expired(t->expire, now_ms);
28302855

28312856
TRACE_ENTER(QMUX_EV_QCC_WAKE, qcc ? qcc->conn : NULL);
2857+
//ABORT_NOW();
28322858

28332859
if (qcc) {
28342860
if (!expired) {
@@ -2881,6 +2907,7 @@ static void _qcc_init(struct qcc *qcc)
28812907
qcc->wait_event.tasklet = NULL;
28822908
qcc->app_ops = NULL;
28832909
qcc->streams_by_id = EB_ROOT_UNIQUE;
2910+
qcc->tx.next = 0;
28842911
LIST_INIT(&qcc->lfctl.frms);
28852912
LIST_INIT(&qcc->tx.frms);
28862913
}

src/quic_tx.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,8 @@ static int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
359359
qc->bytes.tx += tmpbuf.data;
360360
time_sent = now_ms;
361361

362+
//work_gtod(global.tune.pipesize);
363+
362364
for (pkt = first_pkt; pkt; pkt = next_pkt) {
363365
struct quic_cc *cc = &qc->path->cc;
364366

@@ -469,11 +471,11 @@ int qc_purge_txbuf(struct quic_conn *qc, struct buffer *buf)
469471
* Returns the result from qc_send() function.
470472
*/
471473
enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
472-
int max_dgram)
474+
int *max_dgram)
473475
{
474476
struct list send_list = LIST_HEAD_INIT(send_list);
475477
enum quic_tx_err ret = QUIC_TX_ERR_NONE;
476-
int max = max_dgram;
478+
int max = *max_dgram;
477479

478480
TRACE_ENTER(QUIC_EV_CONN_TXPKT, qc);
479481
BUG_ON(qc->mux_state != QC_MUX_READY); /* Only MUX can uses this function so it must be ready. */
@@ -494,14 +496,14 @@ enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
494496

495497
TRACE_STATE("preparing data (from MUX)", QUIC_EV_CONN_TXPKT, qc);
496498
qel_register_send(&send_list, qc->ael, frms);
497-
if (!qc_send(qc, 0, &send_list, max_dgram ? &max : NULL)) {
499+
if (!qc_send(qc, 0, &send_list, *max_dgram ? &max : NULL))
498500
ret = QUIC_TX_ERR_FATAL;
499-
ABORT_NOW();
500-
}
501-
502-
if (max_dgram && !max) {
501+
else if (*max_dgram && !max)
503502
ret = QUIC_TX_ERR_AGAIN;
504-
//ABORT_NOW();
503+
else {
504+
if (*max_dgram)
505+
*max_dgram = *max_dgram - max;
506+
505507
}
506508

507509
TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc);

src/tools.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6958,6 +6958,26 @@ void free_all_file_names()
69586958
HA_RWLOCK_WRUNLOCK(OTHER_LOCK, &file_names.lock);
69596959
}
69606960

6961+
void work_gtod(int usec)
6962+
{
6963+
struct timeval now, expire;
6964+
6965+
gettimeofday(&expire, NULL);
6966+
expire.tv_sec += usec / 1000000;
6967+
expire.tv_usec += usec % 1000000;
6968+
6969+
if (expire.tv_usec >= 1000000) {
6970+
expire.tv_usec -= 1000000;
6971+
expire.tv_sec += 1;
6972+
}
6973+
6974+
do {
6975+
gettimeofday(&now, NULL);
6976+
} while (now.tv_sec < expire.tv_sec ||
6977+
(now.tv_sec == expire.tv_sec &&
6978+
now.tv_usec < expire.tv_usec));
6979+
}
6980+
69616981
/*
69626982
* Local variables:
69636983
* c-indent-level: 8

0 commit comments

Comments
 (0)