Skip to content

Commit bbaf5bc

Browse files
committed
TMP
1 parent d772ecb commit bbaf5bc

File tree

6 files changed

+159
-139
lines changed

6 files changed

+159
-139
lines changed

include/haproxy/quic_pacing-t.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
struct quic_pacer {
88
struct list frms;
99
const struct quic_cc_path *path;
10-
ullong next;
10+
int next;
11+
unsigned int curr;
12+
int pkt_ms;
13+
int sent;
1114
};
1215

1316
#endif /* _HAPROXY_QUIC_PACING_T_H */

include/haproxy/quic_pacing.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,20 @@
55

66
#include <haproxy/list.h>
77
#include <haproxy/quic_frame.h>
8+
#include <haproxy/quic_tx-t.h>
89

910
static inline void quic_pacing_init(struct quic_pacer *pacer,
1011
const struct quic_cc_path *path)
1112
{
1213
LIST_INIT(&pacer->frms);
1314
pacer->path = path;
14-
pacer->next = 0;
15+
//pacer->next = TICK_ETERNITY;
16+
pacer->next = now_ms;
17+
18+
//pacer->curr = now_ms;
19+
pacer->curr = TICK_ETERNITY;
20+
pacer->pkt_ms = 0;
21+
pacer->sent = 0;
1522
}
1623

1724
static inline void quic_pacing_reset(struct quic_pacer *pacer)
@@ -30,15 +37,23 @@ static inline struct list *quic_pacing_frms(struct quic_pacer *pacer)
3037
return &pacer->frms;
3138
}
3239

33-
static inline ullong quic_pacing_ns_pkt(const struct quic_pacer *pacer)
40+
static inline int quic_pacing_ns_pkt(const struct quic_pacer *pacer, int sent)
3441
{
35-
return pacer->path->loss.srtt * 1000000 / (pacer->path->cwnd / pacer->path->mtu + 1);
42+
//return pacer->path->loss.srtt * 1000000 / (pacer->path->cwnd / pacer->path->mtu + 1);
43+
//ullong val = pacer->path->loss.srtt / (pacer->path->cwnd / (pacer->path->mtu * sent) + 1);
44+
//fprintf(stderr, "val=%llu %d/(%lu/(%zu * %d) + 1\n",
45+
// val, pacer->path->loss.srtt, pacer->path->cwnd, pacer->path->mtu, sent);
46+
//return pacer->path->loss.srtt / (pacer->path->cwnd / (pacer->path->mtu * sent) + 1);
47+
return (pacer->path->cwnd / (pacer->path->mtu + 1)) / (pacer->path->loss.srtt + 1) + 1;
3648
}
3749

3850
int quic_pacing_expired(const struct quic_pacer *pacer);
3951

4052
enum quic_tx_err quic_pacing_send(struct quic_pacer *pacer, struct quic_conn *qc);
4153

42-
void quic_pacing_sent_done(struct quic_pacer *pacer, int sent);
54+
int quic_pacing_prepare(struct quic_pacer *pacer);
55+
56+
//void quic_pacing_sent_done(struct quic_pacer *pacer, int sent);
57+
int quic_pacing_sent_done(struct quic_pacer *pacer, int sent, enum quic_tx_err err);
4358

4459
#endif /* _HAPROXY_QUIC_PACING_H */

src/mux_quic.c

Lines changed: 34 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -273,131 +273,26 @@ static inline int qcc_may_expire(struct qcc *qcc)
273273
/* Refresh the timeout on <qcc> if needed depending on its state. */
274274
static void qcc_refresh_timeout(struct qcc *qcc)
275275
{
276-
const struct proxy *px = qcc->proxy;
277-
278-
TRACE_ENTER(QMUX_EV_QCC_WAKE, qcc->conn);
279-
280-
if (!qcc->task) {
281-
TRACE_DEVEL("already expired", QMUX_EV_QCC_WAKE, qcc->conn);
282-
goto leave;
283-
}
284-
285-
/* Check if upper layer is responsible of timeout management. */
286-
if (!qcc_may_expire(qcc)) {
287-
TRACE_DEVEL("not eligible for timeout", QMUX_EV_QCC_WAKE, qcc->conn);
288-
qcc->task->expire = TICK_ETERNITY;
289-
task_queue(qcc->task);
290-
goto leave;
291-
}
292-
293-
/* Frontend timeout management
294-
* - shutdown done -> timeout client-fin
295-
* - detached streams with data left to send -> default timeout
296-
* - stream waiting on incomplete request or no stream yet activated -> timeout http-request
297-
* - idle after stream processing -> timeout http-keep-alive
298-
*
299-
* If proxy stop-stop in progress, immediate or spread close will be
300-
* processed if shutdown already one or connection is idle.
301-
*/
302-
if (!conn_is_back(qcc->conn)) {
303-
if (qcc->nb_hreq && !(qcc->flags & QC_CF_APP_SHUT)) {
304-
TRACE_DEVEL("one or more requests still in progress", QMUX_EV_QCC_WAKE, qcc->conn);
305-
qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout);
306-
task_queue(qcc->task);
307-
goto leave;
308-
}
309-
310-
if ((!LIST_ISEMPTY(&qcc->opening_list) || unlikely(!qcc->largest_bidi_r)) &&
311-
!(qcc->flags & QC_CF_APP_SHUT)) {
312-
int timeout = px->timeout.httpreq;
313-
struct qcs *qcs = NULL;
314-
int base_time;
315-
316-
/* Use start time of first stream waiting on HTTP or
317-
* qcc idle if no stream not yet used.
318-
*/
319-
if (likely(!LIST_ISEMPTY(&qcc->opening_list)))
320-
qcs = LIST_ELEM(qcc->opening_list.n, struct qcs *, el_opening);
321-
base_time = qcs ? qcs->start : qcc->idle_start;
322-
323-
TRACE_DEVEL("waiting on http request", QMUX_EV_QCC_WAKE, qcc->conn, qcs);
324-
qcc->task->expire = tick_add_ifset(base_time, timeout);
325-
}
326-
else {
327-
if (qcc->flags & QC_CF_APP_SHUT) {
328-
TRACE_DEVEL("connection in closing", QMUX_EV_QCC_WAKE, qcc->conn);
329-
qcc->task->expire = tick_add_ifset(now_ms,
330-
qcc->shut_timeout);
331-
}
332-
else {
333-
/* Use http-request timeout if keep-alive timeout not set */
334-
int timeout = tick_isset(px->timeout.httpka) ?
335-
px->timeout.httpka : px->timeout.httpreq;
336-
TRACE_DEVEL("at least one request achieved but none currently in progress", QMUX_EV_QCC_WAKE, qcc->conn);
337-
qcc->task->expire = tick_add_ifset(qcc->idle_start, timeout);
338-
}
339-
340-
/* If proxy soft-stop in progress and connection is
341-
* inactive, close the connection immediately. If a
342-
* close-spread-time is configured, randomly spread the
343-
* timer over a closing window.
344-
*/
345-
if ((qcc->proxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) &&
346-
!(global.tune.options & GTUNE_DISABLE_ACTIVE_CLOSE)) {
347-
348-
/* Wake timeout task immediately if window already expired. */
349-
int remaining_window = tick_isset(global.close_spread_end) ?
350-
tick_remain(now_ms, global.close_spread_end) : 0;
351-
352-
TRACE_DEVEL("proxy disabled, prepare connection soft-stop", QMUX_EV_QCC_WAKE, qcc->conn);
353-
if (remaining_window) {
354-
/* We don't need to reset the expire if it would
355-
* already happen before the close window end.
356-
*/
357-
if (!tick_isset(qcc->task->expire) ||
358-
tick_is_le(global.close_spread_end, qcc->task->expire)) {
359-
/* Set an expire value shorter than the current value
360-
* because the close spread window end comes earlier.
361-
*/
362-
qcc->task->expire = tick_add(now_ms,
363-
statistical_prng_range(remaining_window));
364-
}
365-
}
366-
else {
367-
/* We are past the soft close window end, wake the timeout
368-
* task up immediately.
369-
*/
370-
qcc->task->expire = now_ms;
371-
task_wakeup(qcc->task, TASK_WOKEN_TIMER);
372-
}
373-
}
374-
}
375-
}
376-
377-
/* fallback to default timeout if frontend specific undefined or for
378-
* backend connections.
379-
*/
380-
if (!tick_isset(qcc->task->expire)) {
381-
TRACE_DEVEL("fallback to default timeout", QMUX_EV_QCC_WAKE, qcc->conn);
382-
qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout);
383-
}
384-
385-
task_queue(qcc->task);
386-
387-
leave:
388-
TRACE_LEAVE(QMUX_EV_QCS_NEW, qcc->conn);
389276
}
390277

391278
void qcc_wakeup(struct qcc *qcc)
392279
{
393280
HA_ATOMIC_AND(&qcc->wait_event.tasklet->state, ~TASK_F_USR1);
394281
tasklet_wakeup(qcc->wait_event.tasklet);
282+
283+
//qcc->task->expire = TICK_ETERNITY;
284+
//task_queue(qcc->task);
285+
//TRACE_POINT(QMUX_EV_STRM_WAKE, qcc->conn);
395286
}
396287

397288
static void qcc_wakeup_pacing(struct qcc *qcc)
398289
{
399290
HA_ATOMIC_OR(&qcc->wait_event.tasklet->state, TASK_F_USR1);
400291
tasklet_wakeup(qcc->wait_event.tasklet);
292+
//qcc->task->expire = qcc->tx.pacer.next;
293+
//BUG_ON(tick_is_expired(qcc->task->expire, now_ms));
294+
//task_queue(qcc->task);
295+
//TRACE_POINT(QMUX_EV_STRM_WAKE, qcc->conn);
401296
}
402297

403298
/* Mark a stream as open if it was idle. This can be used on every
@@ -674,7 +569,7 @@ void qcc_notify_buf(struct qcc *qcc, uint64_t free_size)
674569
{
675570
struct qcs *qcs;
676571

677-
TRACE_ENTER(QMUX_EV_QCC_WAKE, qcc->conn);
572+
//TRACE_ENTER(QMUX_EV_QCC_WAKE, qcc->conn);
678573

679574
/* Cannot have a negative buf_in_flight counter */
680575
BUG_ON(qcc->tx.buf_in_flight < free_size);
@@ -700,7 +595,7 @@ void qcc_notify_buf(struct qcc *qcc, uint64_t free_size)
700595
qcs_notify_send(qcs);
701596
}
702597

703-
TRACE_LEAVE(QMUX_EV_QCC_WAKE, qcc->conn);
598+
//TRACE_LEAVE(QMUX_EV_QCC_WAKE, qcc->conn);
704599
}
705600

706601
/* A fatal error is detected locally for <qcc> connection. It should be closed
@@ -2774,7 +2669,7 @@ static void qcc_release(struct qcc *qcc)
27742669
TRACE_LEAVE(QMUX_EV_QCC_END);
27752670
}
27762671

2777-
static void qcc_purge_sending(struct qcc *qcc)
2672+
static int qcc_purge_sending(struct qcc *qcc)
27782673
{
27792674
struct quic_conn *qc = qcc->conn->handle.qc;
27802675
struct quic_pacer *pacer = &qcc->tx.pacer;
@@ -2783,16 +2678,22 @@ static void qcc_purge_sending(struct qcc *qcc)
27832678
ret = quic_pacing_send(pacer, qc);
27842679
if (ret == QUIC_TX_ERR_AGAIN) {
27852680
BUG_ON(LIST_ISEMPTY(quic_pacing_frms(pacer)));
2681+
TRACE_POINT(QMUX_EV_QCC_WAKE, qcc->conn);
27862682
qcc_wakeup_pacing(qcc);
2683+
return 1;
27872684
}
27882685
else if (ret == QUIC_TX_ERR_FATAL) {
27892686
TRACE_DEVEL("error on sending", QMUX_EV_QCC_SEND, qcc->conn);
2687+
TRACE_POINT(QMUX_EV_QCC_WAKE, qcc->conn);
27902688
HA_ATOMIC_AND(&qcc->wait_event.tasklet->state, ~TASK_F_USR1);
27912689
qcc_subscribe_send(qcc);
2690+
return 0;
27922691
}
27932692
else {
2693+
TRACE_POINT(QMUX_EV_QCC_WAKE, qcc->conn);
27942694
if (!LIST_ISEMPTY(quic_pacing_frms(pacer)))
27952695
qcc_subscribe_send(qcc);
2696+
return 0;
27962697
}
27972698
}
27982699

@@ -2803,6 +2704,7 @@ struct task *qcc_io_cb(struct task *t, void *ctx, unsigned int status)
28032704
TRACE_ENTER(QMUX_EV_QCC_WAKE, qcc->conn);
28042705

28052706
if (status & TASK_F_USR1) {
2707+
//ABORT_NOW();
28062708
qcc_purge_sending(qcc);
28072709
return NULL;
28082710
}
@@ -2842,14 +2744,27 @@ static struct task *qcc_timeout_task(struct task *t, void *ctx, unsigned int sta
28422744
TRACE_DEVEL("not expired", QMUX_EV_QCC_WAKE, qcc->conn);
28432745
goto requeue;
28442746
}
2747+
//fprintf(stderr, "woken up after %dms\n", now_ms - qcc->tx.pacer.next);
28452748

2749+
#if 0
28462750
if (!qcc_may_expire(qcc)) {
28472751
TRACE_DEVEL("cannot expired", QMUX_EV_QCC_WAKE, qcc->conn);
28482752
t->expire = TICK_ETERNITY;
28492753
goto requeue;
28502754
}
2755+
#endif
2756+
}
2757+
2758+
if (qcc_purge_sending(qcc)) {
2759+
qcc->task->expire = qcc->tx.pacer.next;
2760+
BUG_ON(tick_is_expired(qcc->task->expire, now_ms));
2761+
TRACE_POINT(QMUX_EV_QCC_WAKE, qcc->conn);
2762+
goto requeue;
28512763
}
2764+
t->expire = TICK_ETERNITY;
2765+
goto requeue;
28522766

2767+
#if 0
28532768
task_destroy(t);
28542769

28552770
if (!qcc) {
@@ -2870,6 +2785,7 @@ static struct task *qcc_timeout_task(struct task *t, void *ctx, unsigned int sta
28702785
qcc_shutdown(qcc);
28712786
qcc_release(qcc);
28722787
}
2788+
#endif
28732789

28742790
out:
28752791
TRACE_LEAVE(QMUX_EV_QCC_WAKE);
@@ -2984,7 +2900,8 @@ static int qmux_init(struct connection *conn, struct proxy *prx,
29842900
}
29852901
qcc->task->process = qcc_timeout_task;
29862902
qcc->task->context = qcc;
2987-
qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout);
2903+
//qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout);
2904+
qcc->task->expire = TICK_ETERNITY;
29882905

29892906
qcc_reset_idle_start(qcc);
29902907
LIST_INIT(&qcc->opening_list);

src/qmux_trace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ void qmux_dump_qcc_info(struct buffer *msg, const struct qcc *qcc)
139139
chunk_appendf(msg, " qc=%p", qcc->conn->handle.qc);
140140
chunk_appendf(msg, " .sc=%llu .hreq=%llu .flg=0x%04x", (ullong)qcc->nb_sc, (ullong)qcc->nb_hreq, qcc->flags);
141141

142-
chunk_appendf(msg, " .tx=%llu %llu/%llu bwnd=%llu/%llu",
142+
chunk_appendf(msg, " .tx=%llu %llu/%llu bwnd=%llu/%llu exp=%llu",
143143
(ullong)qcc->tx.fc.off_soft, (ullong)qcc->tx.fc.off_real, (ullong)qcc->tx.fc.limit,
144-
(ullong)qcc->tx.buf_in_flight, (ullong)qc->path->cwnd);
144+
(ullong)qcc->tx.buf_in_flight, (ullong)qc->path->cwnd, qcc->task && tick_isset(qcc->task->expire) ? (ullong)tick_remain(now_ms, qcc->task->expire) : 0);
145145
}
146146

147147
void qmux_dump_qcs_info(struct buffer *msg, const struct qcs *qcs)

0 commit comments

Comments
 (0)