]> git.kaiwu.me - nginx.git/commitdiff
QUIC: optimized connection frame threshold.
authorRoman Arutyunyan <arut@nginx.com>
Fri, 4 Apr 2025 13:39:05 +0000 (17:39 +0400)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Tue, 15 Apr 2025 15:01:36 +0000 (19:01 +0400)
Previosly the threshold was hardcoded at 10000.  This value is too low for
high BDP networks.  For example, if all frames are STREAM frames, and MTU
is 1500, the upper limit for congestion window would be roughly 15M
(10000 * 1500).  With 100ms RTT it's just a 1.2Gbps network (15M * 10 * 8).
In reality, the limit is even lower because of other frame types.  Also,
the number of frames that could be used simultaneously depends on the total
amount of data buffered in all server streams, and client flow control.

The change sets frame threshold based on max concurrent streams and stream
buffer size, the product of which is the maximum number of in-flight stream
data in all server streams at any moment.  The value is divided by 2000 to
account for a typical MTU 1500 and the fact that not all frames are STREAM
frames.

src/event/quic/ngx_event_quic.c
src/event/quic/ngx_event_quic_connection.h
src/event/quic/ngx_event_quic_frames.c

index 49d30e82acf60e94250aee7051295d1fd23080fb..4682ecad9fc17e76120f3e7f39b86663061d59bf 100644 (file)
@@ -315,6 +315,10 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
     qc->congestion.mtu = NGX_QUIC_MIN_INITIAL_SIZE;
     qc->congestion.recovery_start = ngx_current_msec - 1;
 
+    qc->max_frames = (conf->max_concurrent_streams_uni
+                      + conf->max_concurrent_streams_bidi)
+                     * conf->stream_buffer_size / 2000;
+
     if (pkt->validated && pkt->retried) {
         qc->tp.retry_scid.len = pkt->dcid.len;
         qc->tp.retry_scid.data = ngx_pstrdup(c->pool, &pkt->dcid);
index 716d62308ea68b0851eab69243f0bf3f9db29b67..04cda859ee08df2f56f7e73707e087091ee7e7b7 100644 (file)
@@ -261,6 +261,7 @@ struct ngx_quic_connection_s {
     ngx_buf_t                        *free_shadow_bufs;
 
     ngx_uint_t                        nframes;
+    ngx_uint_t                        max_frames;
 #ifdef NGX_QUIC_DEBUG_ALLOC
     ngx_uint_t                        nbufs;
     ngx_uint_t                        nshadowbufs;
index 6ea908cc1ca27135829804d7b75e749e2b3e4173..888e8bda289b27df4691b2fdb1c8c4127c7bf099 100644 (file)
@@ -214,7 +214,7 @@ ngx_quic_alloc_frame(ngx_connection_t *c)
                        "quic reuse frame n:%ui", qc->nframes);
 #endif
 
-    } else if (qc->nframes < 10000) {
+    } else if (qc->nframes < qc->max_frames) {
         frame = ngx_palloc(c->pool, sizeof(ngx_quic_frame_t));
         if (frame == NULL) {
             return NULL;