mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-05-16 22:58:02 +00:00
MEDIUM: mux-quic: increase flow-control on each bufsize
Recently, QCS Rx allocation buffer method has been improved. It is now possible to allocate multiple buffers per QCS instances, which was necessary to improve HTTP/3 POST throughput. However, a limitation remained related to the emission of MAX_STREAM_DATA. These frames are only emitted once at least half of the receive capacity has been consumed by its QCS instance. This may be too restrictive when a client need to upload a large payload. Improve this by adjusting MAX_STREAM_DATA allocation. If QCS capacity is still limited to 1 or 2 buffers max, the old calcul is still used. This is necessary when user has limited upload throughput via their configuration. If QCS capacity is more than 2 buffers, a new frame is emitted if at least a buffer was consumed. This patch has reduced number of STREAM_DATA_BLOCKED frames received in POST tests with some specific clients.
This commit is contained in:
parent
2ccfebcebf
commit
14a3fb679f
@ -156,7 +156,7 @@ struct qcs {
|
||||
struct eb_root bufs; /* receive buffers tree ordered by offset */
|
||||
struct buffer app_buf; /* receive buffer used by stconn layer */
|
||||
uint64_t msd; /* current max-stream-data limit to enforce */
|
||||
uint64_t msd_init; /* initial max-stream-data */
|
||||
uint64_t msd_base; /* max-stream-data previous to latest update */
|
||||
} rx;
|
||||
struct {
|
||||
struct quic_fctl fc; /* stream flow control applied on sending */
|
||||
|
@ -173,7 +173,7 @@ static struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type)
|
||||
else if (quic_stream_is_remote(qcc, id)) {
|
||||
qcs->rx.msd = qcc->lfctl.msd_uni_r;
|
||||
}
|
||||
qcs->rx.msd_init = qcs->rx.msd;
|
||||
qcs->rx.msd_base = 0;
|
||||
|
||||
qcs->wait_event.tasklet = NULL;
|
||||
qcs->wait_event.events = 0;
|
||||
@ -1198,6 +1198,7 @@ static void qcs_consume(struct qcs *qcs, uint64_t bytes, struct qc_stream_rxbuf
|
||||
struct qcc *qcc = qcs->qcc;
|
||||
struct quic_frame *frm;
|
||||
enum ncb_ret ret;
|
||||
uint64_t diff, inc = 0;
|
||||
|
||||
TRACE_ENTER(QMUX_EV_QCS_RECV, qcc->conn, qcs);
|
||||
|
||||
@ -1218,7 +1219,24 @@ static void qcs_consume(struct qcs *qcs, uint64_t bytes, struct qc_stream_rxbuf
|
||||
if (qcs->flags & QC_SF_SIZE_KNOWN)
|
||||
goto conn_fctl;
|
||||
|
||||
if (qcs->rx.msd - qcs->rx.offset < qcs->rx.msd_init / 2) {
|
||||
/* Check if a MAX_STREAM_DATA frame should be emitted, determined by
|
||||
* the consumed capacity. If no more than 2 Rx buffers can be allocated
|
||||
* per QCS, the limit is set to half the capacity. Else, the limit is
|
||||
* set to match bufsize.
|
||||
*/
|
||||
if (qcs->rx.msd - qcs->rx.msd_base < qmux_stream_rx_bufsz() * 2) {
|
||||
if ((qcs->rx.offset - qcs->rx.msd_base) * 2 >= qcs->rx.msd - qcs->rx.msd_base)
|
||||
inc = qcs->rx.offset - qcs->rx.msd_base;
|
||||
}
|
||||
else {
|
||||
diff = qcs->rx.offset - qcs->rx.msd_base;
|
||||
while (diff >= qmux_stream_rx_bufsz()) {
|
||||
inc += qmux_stream_rx_bufsz();
|
||||
diff -= qmux_stream_rx_bufsz();
|
||||
}
|
||||
}
|
||||
|
||||
if (inc) {
|
||||
TRACE_DATA("increase stream credit via MAX_STREAM_DATA", QMUX_EV_QCS_RECV, qcc->conn, qcs);
|
||||
frm = qc_frm_alloc(QUIC_FT_MAX_STREAM_DATA);
|
||||
if (!frm) {
|
||||
@ -1226,7 +1244,8 @@ static void qcs_consume(struct qcs *qcs, uint64_t bytes, struct qc_stream_rxbuf
|
||||
return;
|
||||
}
|
||||
|
||||
qcs->rx.msd = qcs->rx.offset + qcs->rx.msd_init;
|
||||
qcs->rx.msd += inc;
|
||||
qcs->rx.msd_base += inc;
|
||||
|
||||
frm->max_stream_data.id = qcs->id;
|
||||
frm->max_stream_data.max_stream_data = qcs->rx.msd;
|
||||
|
Loading…
Reference in New Issue
Block a user