QUIC: all-levels commit and revert functions.

Previously, these functions operated on a per-level basis.  This however
resulted in excessive logging of in_flight and will also led to extra
work detecting underutilized congestion window in the followup patches.
This commit is contained in:
Roman Arutyunyan 2025-03-09 16:09:28 +04:00
parent 74b0684faf
commit 6e06f53917

View File

@ -45,9 +45,9 @@
static ngx_int_t ngx_quic_create_datagrams(ngx_connection_t *c); static ngx_int_t ngx_quic_create_datagrams(ngx_connection_t *c);
static void ngx_quic_commit_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx); static void ngx_quic_commit_send(ngx_connection_t *c);
static void ngx_quic_revert_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, static void ngx_quic_revert_send(ngx_connection_t *c,
uint64_t pnum); uint64_t preserved_pnum[NGX_QUIC_SEND_CTX_LAST]);
#if ((NGX_HAVE_UDP_SEGMENT) && (NGX_HAVE_MSGHDR_MSG_CONTROL)) #if ((NGX_HAVE_UDP_SEGMENT) && (NGX_HAVE_MSGHDR_MSG_CONTROL))
static ngx_uint_t ngx_quic_allow_segmentation(ngx_connection_t *c); static ngx_uint_t ngx_quic_allow_segmentation(ngx_connection_t *c);
static ngx_int_t ngx_quic_create_segments(ngx_connection_t *c); static ngx_int_t ngx_quic_create_segments(ngx_connection_t *c);
@ -127,6 +127,10 @@ ngx_quic_create_datagrams(ngx_connection_t *c)
cg = &qc->congestion; cg = &qc->congestion;
path = qc->path; path = qc->path;
#if (NGX_SUPPRESS_WARN)
ngx_memzero(preserved_pnum, sizeof(preserved_pnum));
#endif
while (cg->in_flight < cg->window) { while (cg->in_flight < cg->window) {
p = dst; p = dst;
@ -150,12 +154,7 @@ ngx_quic_create_datagrams(ngx_connection_t *c)
if (min > len) { if (min > len) {
/* padding can't be applied - avoid sending the packet */ /* padding can't be applied - avoid sending the packet */
ngx_quic_revert_send(c, preserved_pnum);
while (i-- > 0) {
ctx = &qc->send_ctx[i];
ngx_quic_revert_send(c, ctx, preserved_pnum[i]);
}
return NGX_OK; return NGX_OK;
} }
@ -180,17 +179,12 @@ ngx_quic_create_datagrams(ngx_connection_t *c)
} }
if (n == NGX_AGAIN) { if (n == NGX_AGAIN) {
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { ngx_quic_revert_send(c, preserved_pnum);
ngx_quic_revert_send(c, &qc->send_ctx[i], preserved_pnum[i]);
}
ngx_add_timer(&qc->push, NGX_QUIC_SOCKET_RETRY_DELAY); ngx_add_timer(&qc->push, NGX_QUIC_SOCKET_RETRY_DELAY);
break; break;
} }
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { ngx_quic_commit_send(c);
ngx_quic_commit_send(c, &qc->send_ctx[i]);
}
path->sent += len; path->sent += len;
} }
@ -200,17 +194,21 @@ ngx_quic_create_datagrams(ngx_connection_t *c)
static void static void
ngx_quic_commit_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx) ngx_quic_commit_send(ngx_connection_t *c)
{ {
ngx_uint_t i;
ngx_queue_t *q; ngx_queue_t *q;
ngx_quic_frame_t *f; ngx_quic_frame_t *f;
ngx_quic_send_ctx_t *ctx;
ngx_quic_congestion_t *cg; ngx_quic_congestion_t *cg;
ngx_quic_connection_t *qc; ngx_quic_connection_t *qc;
qc = ngx_quic_get_connection(c); qc = ngx_quic_get_connection(c);
cg = &qc->congestion; cg = &qc->congestion;
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
ctx = &qc->send_ctx[i];
while (!ngx_queue_empty(&ctx->sending)) { while (!ngx_queue_empty(&ctx->sending)) {
q = ngx_queue_head(&ctx->sending); q = ngx_queue_head(&ctx->sending);
@ -227,6 +225,7 @@ ngx_quic_commit_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
ngx_quic_free_frame(c, f); ngx_quic_free_frame(c, f);
} }
} }
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion send if:%uz", cg->in_flight); "quic congestion send if:%uz", cg->in_flight);
@ -234,19 +233,30 @@ ngx_quic_commit_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
static void static void
ngx_quic_revert_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, ngx_quic_revert_send(ngx_connection_t *c, uint64_t pnum[NGX_QUIC_SEND_CTX_LAST])
uint64_t pnum)
{ {
ngx_uint_t i;
ngx_queue_t *q; ngx_queue_t *q;
ngx_quic_send_ctx_t *ctx;
ngx_quic_connection_t *qc;
while (!ngx_queue_empty(&ctx->sending)) { qc = ngx_quic_get_connection(c);
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
ctx = &qc->send_ctx[i];
if (ngx_queue_empty(&ctx->sending)) {
continue;
}
do {
q = ngx_queue_last(&ctx->sending); q = ngx_queue_last(&ctx->sending);
ngx_queue_remove(q); ngx_queue_remove(q);
ngx_queue_insert_head(&ctx->frames, q); ngx_queue_insert_head(&ctx->frames, q);
} } while (!ngx_queue_empty(&ctx->sending));
ctx->pnum = pnum; ctx->pnum = pnum[i];
}
} }
@ -311,13 +321,13 @@ ngx_quic_create_segments(ngx_connection_t *c)
size_t len, segsize; size_t len, segsize;
ssize_t n; ssize_t n;
u_char *p, *end; u_char *p, *end;
uint64_t preserved_pnum; ngx_uint_t nseg, level;
ngx_uint_t nseg;
ngx_quic_path_t *path; ngx_quic_path_t *path;
ngx_quic_send_ctx_t *ctx; ngx_quic_send_ctx_t *ctx;
ngx_quic_congestion_t *cg; ngx_quic_congestion_t *cg;
ngx_quic_connection_t *qc; ngx_quic_connection_t *qc;
static u_char dst[NGX_QUIC_MAX_UDP_SEGMENT_BUF]; static u_char dst[NGX_QUIC_MAX_UDP_SEGMENT_BUF];
static uint64_t preserved_pnum[NGX_QUIC_SEND_CTX_LAST];
qc = ngx_quic_get_connection(c); qc = ngx_quic_get_connection(c);
cg = &qc->congestion; cg = &qc->congestion;
@ -335,7 +345,8 @@ ngx_quic_create_segments(ngx_connection_t *c)
nseg = 0; nseg = 0;
preserved_pnum = ctx->pnum; level = ctx - qc->send_ctx;
preserved_pnum[level] = ctx->pnum;
for ( ;; ) { for ( ;; ) {
@ -369,19 +380,18 @@ ngx_quic_create_segments(ngx_connection_t *c)
} }
if (n == NGX_AGAIN) { if (n == NGX_AGAIN) {
ngx_quic_revert_send(c, ctx, preserved_pnum); ngx_quic_revert_send(c, preserved_pnum);
ngx_add_timer(&qc->push, NGX_QUIC_SOCKET_RETRY_DELAY); ngx_add_timer(&qc->push, NGX_QUIC_SOCKET_RETRY_DELAY);
break; break;
} }
ngx_quic_commit_send(c, ctx); ngx_quic_commit_send(c);
path->sent += n; path->sent += n;
p = dst; p = dst;
nseg = 0; nseg = 0;
preserved_pnum = ctx->pnum; preserved_pnum[level] = ctx->pnum;
} }
} }