Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 19 Sep 2020 19:38:43 +0000 (UTC)
From:      Jochen Neumeister <joneum@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r549054 - in head/www/nginx: . files
Message-ID:  <202009191938.08JJchdP035757@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: joneum
Date: Sat Sep 19 19:38:43 2020
New Revision: 549054
URL: https://svnweb.freebsd.org/changeset/ports/549054

Log:
  Add third-party h2 auto-tune support
  
  PR:		249259
  Sponsored by:	Netzkommunue GmbH

Added:
  head/www/nginx/files/extra-patch-h2-autotune   (contents, props changed)
Modified:
  head/www/nginx/Makefile
  head/www/nginx/Makefile.extmod
  head/www/nginx/Makefile.options.desc

Modified: head/www/nginx/Makefile
==============================================================================
--- head/www/nginx/Makefile	Sat Sep 19 19:32:52 2020	(r549053)
+++ head/www/nginx/Makefile	Sat Sep 19 19:38:43 2020	(r549054)
@@ -75,8 +75,8 @@ OPTIONS_GROUP_HTTPGRP=	GOOGLE_PERFTOOLS HTTP HTTP_ADDI
 	HTTP_CACHE HTTP_DAV HTTP_FLV HTTP_GUNZIP_FILTER HTTP_GZIP_STATIC \
 	HTTP_IMAGE_FILTER HTTP_MP4 HTTP_PERL HTTP_RANDOM_INDEX HTTP_REALIP \
 	HTTP_REWRITE HTTP_SECURE_LINK HTTP_SLICE HTTP_SLICE_AHEAD \
-	HTTP_SSL HTTP_STATUS HTTP_SUB HTTP_XSLT HTTPV2 STREAM STREAM_SSL \
-	STREAM_SSL_PREREAD
+	HTTP_SSL HTTP_STATUS HTTP_SUB HTTP_XSLT HTTPV2 HTTPV2_AUTOTUNE \
+	STREAM STREAM_SSL STREAM_SSL_PREREAD
 # External modules (arrayvar MUST appear after devel_kit for build-dep)
 OPTIONS_GROUP_HTTPGRP+=	AJP AWS_AUTH BROTLI CACHE_PURGE CLOJURE CT DEVEL_KIT \
 	ARRAYVAR DRIZZLE DYNAMIC_TLS DYNAMIC_UPSTREAM ECHO ENCRYPTSESSION \

Modified: head/www/nginx/Makefile.extmod
==============================================================================
--- head/www/nginx/Makefile.extmod	Sat Sep 19 19:32:52 2020	(r549053)
+++ head/www/nginx/Makefile.extmod	Sat Sep 19 19:38:43 2020	(r549054)
@@ -194,6 +194,10 @@ HTTP_VIDEO_THUMBEXTRACTOR_VARS=		DSO_EXTMODS+=vte
 HTTP_ZIP_GH_TUPLE=	rtm-ctrlz:mod_zip:cfd0be4:mod_zip
 HTTP_ZIP_VARS=		DSO_EXTMODS+=mod_zip
 
+HTTPV2_AUTOTUNE_IMPLIES=HTTPV2
+HTTPV2_AUTOTUNE_CONFIGURE_ON=	--with-http_v2_autotune_upload
+HTTPV2_AUTOTUNE_EXTRA_PATCHES=	${PATCHDIR}/extra-patch-h2-autotune
+
 ICONV_IMPLIES=		DEVEL_KIT
 ICONV_USES=		iconv
 ICONV_GH_TUPLE=		calio:iconv-nginx-module:v0.14:iconv

Modified: head/www/nginx/Makefile.options.desc
==============================================================================
--- head/www/nginx/Makefile.options.desc	Sat Sep 19 19:32:52 2020	(r549053)
+++ head/www/nginx/Makefile.options.desc	Sat Sep 19 19:38:43 2020	(r549054)
@@ -24,6 +24,7 @@ GSSAPI_DESC=			GSSAPI implementation (imply HTTP_AUTH_
 HEADERS_MORE_DESC=		3rd party headers_more module
 HTTPGRP_DESC=			Modules that require HTTP module
 HTTPV2_DESC=			Enable HTTP/2 protocol support (SSL req.)
+HTTPV2_AUTOTUNE_DESC=		Enable HTTP/2 upload auto-tuning
 HTTP_ACCEPT_LANGUAGE_DESC=	3rd party accept_language module
 HTTP_ADDITION_DESC=		Enable http_addition module
 HTTP_AUTH_DIGEST_DESC=		3rd party http_authdigest module

Added: head/www/nginx/files/extra-patch-h2-autotune
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/nginx/files/extra-patch-h2-autotune	Sat Sep 19 19:38:43 2020	(r549054)
@@ -0,0 +1,449 @@
+diff -r 7015f26aef90 -r 1739da077a8e auto/modules
+--- auto/modules	Wed Jul 29 13:28:04 2020 +0300
++++ auto/modules	Wed Aug 26 15:51:41 2020 -0700
+@@ -420,6 +420,15 @@
+         ngx_module_libs=
+         ngx_module_link=$HTTP_V2
+ 
++        if [ $HTTP_V2 = YES -a $HTTP_V2_AUTOTUNE_UPLOAD = YES ]; then
++             have=NGX_HTTP_V2_AUTOTUNE_UPLOAD . auto/have
++
++             ngx_module_deps="$ngx_module_deps \
++                             src/http/v2/ngx_autotune_upload.h"
++             ngx_module_srcs="$ngx_module_srcs \
++                             src/http/v2/ngx_autotune_upload.c"
++        fi
++
+         . auto/module
+     fi
+ 
+diff -r 7015f26aef90 -r 1739da077a8e auto/options
+--- auto/options	Wed Jul 29 13:28:04 2020 +0300
++++ auto/options	Wed Aug 26 15:51:41 2020 -0700
+@@ -59,6 +59,7 @@
+ HTTP_GZIP=YES
+ HTTP_SSL=NO
+ HTTP_V2=NO
++HTTP_V2_AUTOTUNE_UPLOAD=NO
+ HTTP_SSI=YES
+ HTTP_REALIP=NO
+ HTTP_XSLT=NO
+@@ -224,6 +225,7 @@
+ 
+         --with-http_ssl_module)          HTTP_SSL=YES               ;;
+         --with-http_v2_module)           HTTP_V2=YES                ;;
++        --with-http_v2_autotune_upload)  HTTP_V2_AUTOTUNE_UPLOAD=YES;;
+         --with-http_realip_module)       HTTP_REALIP=YES            ;;
+         --with-http_addition_module)     HTTP_ADDITION=YES          ;;
+         --with-http_xslt_module)         HTTP_XSLT=YES              ;;
+diff -r 7015f26aef90 -r 1739da077a8e src/http/v2/ngx_autotune_upload.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ src/http/v2/ngx_autotune_upload.c	Wed Aug 26 15:51:41 2020 -0700
+@@ -0,0 +1,198 @@
++/*
++ * Copyright (C) 2020 Cloudflare, Inc.
++ */
++
++#include <ngx_http.h>
++#include <ngx_http_v2_module.h>
++#include <ngx_autotune_upload.h>
++
++static void *ngx_prealloc(ngx_pool_t *pool, void *p, size_t size);
++static void *ngx_realloc(void *oldp, size_t size, ngx_log_t *log);
++
++static ngx_int_t ngx_resize_buf(ngx_pool_t *pool, ngx_buf_t *buf, size_t nsize);
++
++
++static void *
++ngx_prealloc(ngx_pool_t *pool, void *p, size_t size)
++{
++    ngx_pool_large_t *l;
++    void *newp;
++
++    for (l = pool->large; l; l = l->next) {
++        if (p == l->alloc) {
++            ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
++                           "prealloc: %p", l->alloc);
++
++            newp = ngx_realloc(l->alloc, size, pool->log);
++            if (newp) {
++                l->alloc = newp;
++
++                return newp;
++            } else {
++                return NULL;
++           }
++        }
++    }
++
++    /* not found */
++    return NULL;
++}
++
++
++static void *
++ngx_realloc(void *oldp, size_t size, ngx_log_t *log)
++{
++    void *newp;
++
++    newp = realloc(oldp, size);
++    if (newp == NULL) {
++        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
++                      "realloc(%uz) failed", size);
++    }
++
++    ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0, "realloc: %p:%uz", newp, size);
++
++    return newp;
++}
++
++
++/* resize the buffer to the new size */
++static ngx_int_t
++ngx_resize_buf(ngx_pool_t *pool, ngx_buf_t *buf, size_t nsize)
++{
++    void *nbuf = ngx_prealloc(pool, buf->start, nsize);
++
++    if (!nbuf) {
++        return NGX_ERROR;
++    }
++
++    /* if buf->start is moved to a new location */
++    if (nbuf != buf->start) {
++        buf->pos = (u_char *)nbuf + (buf->pos - buf->start);
++        buf->last = (u_char *)nbuf + (buf->last - buf->start);
++    }
++
++    /* resize buffer */
++    buf->start = nbuf;
++    buf->end = (u_char *)nbuf + nsize;
++
++    return NGX_OK;
++}
++
++
++/* get current TCP RTT (ms) of the connection */
++ngx_int_t
++ngx_tcp_rtt_ms(int fd)
++{
++#if (NGX_HAVE_TCP_INFO)
++    struct tcp_info  ti;
++    socklen_t        len;
++
++    len = sizeof(struct tcp_info);
++    if (getsockopt(fd, IPPROTO_TCP, TCP_INFO, &ti, &len) == 0) {
++        return ti.tcpi_rtt / 1000;
++    }
++#endif
++
++    return NGX_ERROR;
++}
++
++
++/* return current timestamp (ms) */
++ngx_msec_int_t
++ngx_timestamp_ms()
++{
++    ngx_time_t *tp = ngx_timeofday();
++
++    return tp->sec * 1000 + tp->msec;
++}
++
++
++/*
++ * double the buffer size based on the current BDP.
++ * returns the new window size if resized.
++ * returns the current window size if not resized.
++ * if resizing fails, returns 0.
++ */
++size_t
++ngx_autotune_client_body_buffer(ngx_http_request_t *r,
++    size_t window)
++{
++    ngx_buf_t                 *buf;
++    ngx_http_v2_stream_t      *stream;
++    ngx_msec_int_t             ts_now;
++    ngx_http_v2_loc_conf_t    *h2lcf;
++    size_t                     max_window;
++
++    h2lcf = ngx_http_get_module_loc_conf(r, ngx_http_v2_module);
++    max_window = h2lcf->max_client_body_buffer_size;
++
++    /* no autotuning configured */
++    if (!max_window) {
++        return window;
++    }
++
++    /* if max_window is smaller than the current window, do nothing */
++    if (window >= max_window) {
++        return window;
++    }
++
++    stream = r->stream;
++    buf = r->request_body->buf;
++
++    /* if rtt is not available, do nothing */
++    if (stream->rtt == NGX_ERROR) {
++        return window;
++    }
++
++    ts_now = ngx_timestamp_ms();
++
++    if (ts_now >= (stream->ts_checkpoint + stream->rtt)) {
++        size_t cur_win = (buf->end - buf->start);
++        size_t new_win = ngx_min(cur_win * 2 , max_window);
++
++        /* if already on the max size, do nothing */
++        if (cur_win >= max_window) {
++            return window;
++        }
++
++        /* min rtt is 1ms to prevent BDP from becoming zero. */
++        ngx_uint_t rtt = ngx_max(stream->rtt, 1);
++
++        /*
++         * elapsed time (ms) from last checkpoint. mininum value is 1 to
++         * prevent from dividing by zero in BDP calculation
++         */
++        ngx_uint_t elapsed = ngx_max(ts_now - stream->ts_checkpoint, 1);
++
++        /* calculate BDP (bytes) = rtt * bw */
++        ngx_uint_t bdp = rtt * stream->bytes_body_read / elapsed;
++
++        ngx_log_debug4(NGX_LOG_DEBUG_HTTP, stream->connection->connection->log, 0,
++                       "http2 autotune sid:%ui rtt:%z bdp:%z win:%z",
++                       stream->node->id, stream->rtt, bdp, window);
++
++        stream->bytes_body_read = 0;
++        stream->ts_checkpoint = ts_now;
++
++        /*
++         * check if we need to bump the buffer size
++         * based on the heuristic condition
++         */
++        if (bdp > (window / 4)) {
++            if (ngx_resize_buf(r->pool, buf, new_win) != NGX_OK) {
++                return 0;
++            }
++
++            ngx_log_debug4(NGX_LOG_DEBUG_HTTP,
++                           stream->connection->connection->log, 0,
++                           "http2 autotune sid:%ui rtt:%z resized:%z->%z",
++                           stream->node->id, stream->rtt, window,
++                           window + (new_win - cur_win));
++
++            return window + (new_win - cur_win);
++        }
++    }
++
++    return window;
++}
+diff -r 7015f26aef90 -r 1739da077a8e src/http/v2/ngx_autotune_upload.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ src/http/v2/ngx_autotune_upload.h	Wed Aug 26 15:51:41 2020 -0700
+@@ -0,0 +1,25 @@
++/*
++ * Copyright (C) 2020 Cloudflare, Inc.
++ */
++
++#ifndef _NGX_AUTOTUNE_UPLOAD_H_INCLUDED_
++#define _NGX_AUTOTUNE_UPLOAD_H_INCLUDED_
++
++#include <ngx_core.h>
++
++
++/* the maximum size of the receiver window */
++#define NGX_HTTP_V2_MAX_CLIENT_BODY_BUFFER_SIZE (64*1024*1024)
++
++
++/* get current TCP RTT (ms) of the connection */
++ngx_int_t ngx_tcp_rtt_ms(int fd);
++
++/* return current timestamp (ms) */
++ngx_msec_int_t ngx_timestamp_ms();
++
++/* auto resize the buffer */
++size_t ngx_autotune_client_body_buffer(ngx_http_request_t *r, size_t window);
++
++
++#endif
+diff -r 7015f26aef90 -r 1739da077a8e src/http/v2/ngx_http_v2.c
+--- src/http/v2/ngx_http_v2.c	Wed Jul 29 13:28:04 2020 +0300
++++ src/http/v2/ngx_http_v2.c	Wed Aug 26 15:51:41 2020 -0700
+@@ -11,6 +11,10 @@
+ #include <ngx_http_v2_module.h>
+ 
+ 
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++#include <ngx_autotune_upload.h>
++#endif
++
+ typedef struct {
+     ngx_str_t           name;
+     ngx_uint_t          offset;
+@@ -1122,6 +1126,10 @@
+     pos += size;
+     h2c->state.length -= size;
+ 
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++    stream->bytes_body_read += size;
++#endif
++
+     if (h2c->state.length) {
+         return ngx_http_v2_state_save(h2c, pos, end,
+                                       ngx_http_v2_state_read_data);
+@@ -3211,6 +3219,12 @@
+ 
+     h2c->priority_limit += h2scf->concurrent_streams;
+ 
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++    stream->bytes_body_read = 0;
++    stream->rtt = ngx_tcp_rtt_ms(r->connection->fd);
++    stream->ts_checkpoint = ngx_timestamp_ms();
++#endif
++
+     return stream;
+ }
+ 
+@@ -4323,6 +4337,15 @@
+         return NGX_AGAIN;
+     }
+ 
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++    window = ngx_autotune_client_body_buffer(r, window);
++
++    /* resizing failed */
++    if (!window) {
++        return NGX_HTTP_INTERNAL_SERVER_ERROR;
++    }
++#endif
++
+     if (ngx_http_v2_send_window_update(h2c, stream->node->id,
+                                        window - stream->recv_window)
+         == NGX_ERROR)
+diff -r 7015f26aef90 -r 1739da077a8e src/http/v2/ngx_http_v2.h
+--- src/http/v2/ngx_http_v2.h	Wed Jul 29 13:28:04 2020 +0300
++++ src/http/v2/ngx_http_v2.h	Wed Aug 26 15:51:41 2020 -0700
+@@ -210,6 +210,15 @@
+ 
+     ngx_pool_t                      *pool;
+ 
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++    /* how much client request body read */
++    ngx_uint_t                       bytes_body_read;
++    /* timestamp of next checkpoint */
++    ngx_msec_int_t                   ts_checkpoint;
++    /* rtt(ms) of the connection */
++    ngx_int_t                        rtt;
++#endif
++
+     unsigned                         waiting:1;
+     unsigned                         blocked:1;
+     unsigned                         exhausted:1;
+diff -r 7015f26aef90 -r 1739da077a8e src/http/v2/ngx_http_v2_module.c
+--- src/http/v2/ngx_http_v2_module.c	Wed Jul 29 13:28:04 2020 +0300
++++ src/http/v2/ngx_http_v2_module.c	Wed Aug 26 15:51:41 2020 -0700
+@@ -10,6 +10,9 @@
+ #include <ngx_http.h>
+ #include <ngx_http_v2_module.h>
+ 
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++#include <ngx_autotune_upload.h>
++#endif
+ 
+ static ngx_int_t ngx_http_v2_add_variables(ngx_conf_t *cf);
+ 
+@@ -38,6 +41,10 @@
+ static char *ngx_http_v2_chunk_size(ngx_conf_t *cf, void *post, void *data);
+ static char *ngx_http_v2_spdy_deprecated(ngx_conf_t *cf, ngx_command_t *cmd,
+     void *conf);
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++static char *ngx_http_v2_max_client_body_buffer_size(ngx_conf_t *cf, void *post,
++    void *data);
++#endif
+ 
+ 
+ static ngx_conf_post_t  ngx_http_v2_recv_buffer_size_post =
+@@ -50,6 +57,10 @@
+     { ngx_http_v2_streams_index_mask };
+ static ngx_conf_post_t  ngx_http_v2_chunk_size_post =
+     { ngx_http_v2_chunk_size };
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++static ngx_conf_post_t  ngx_http_v2_max_client_body_buffer_size_post =
++    { ngx_http_v2_max_client_body_buffer_size };
++#endif
+ 
+ 
+ static ngx_command_t  ngx_http_v2_commands[] = {
+@@ -208,6 +219,15 @@
+       0,
+       NULL },
+ 
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++    { ngx_string("http2_max_client_body_buffer_size"),
++      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
++      ngx_conf_set_size_slot,
++      NGX_HTTP_LOC_CONF_OFFSET,
++      offsetof(ngx_http_v2_loc_conf_t, max_client_body_buffer_size),
++      &ngx_http_v2_max_client_body_buffer_size_post },
++#endif
++
+       ngx_null_command
+ };
+ 
+@@ -423,6 +443,10 @@
+     h2lcf->push_preload = NGX_CONF_UNSET;
+     h2lcf->push = NGX_CONF_UNSET;
+ 
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++    h2lcf->max_client_body_buffer_size = NGX_CONF_UNSET_SIZE;
++#endif
++
+     return h2lcf;
+ }
+ 
+@@ -443,6 +467,12 @@
+ 
+     ngx_conf_merge_value(conf->push_preload, prev->push_preload, 0);
+ 
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++    /* default is 0: no auto tuning */
++    ngx_conf_merge_size_value(conf->max_client_body_buffer_size,
++                              prev->max_client_body_buffer_size, 0);
++#endif
++
+     return NGX_CONF_OK;
+ }
+ 
+@@ -608,3 +638,19 @@
+ 
+     return NGX_CONF_OK;
+ }
++
++
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++static char *
++ngx_http_v2_max_client_body_buffer_size(ngx_conf_t *cf, void *post,
++    void *data)
++{
++    size_t *sp = data;
++
++    if (*sp > NGX_HTTP_V2_MAX_CLIENT_BODY_BUFFER_SIZE) {
++        *sp = NGX_HTTP_V2_MAX_CLIENT_BODY_BUFFER_SIZE;
++    }
++
++    return NGX_CONF_OK;
++}
++#endif
+diff -r 7015f26aef90 -r 1739da077a8e src/http/v2/ngx_http_v2_module.h
+--- src/http/v2/ngx_http_v2_module.h	Wed Jul 29 13:28:04 2020 +0300
++++ src/http/v2/ngx_http_v2_module.h	Wed Aug 26 15:51:41 2020 -0700
+@@ -41,6 +41,10 @@
+ 
+     ngx_flag_t                      push;
+     ngx_array_t                    *pushes;
++
++#if (NGX_HTTP_V2_AUTOTUNE_UPLOAD)
++    size_t                          max_client_body_buffer_size;
++#endif
+ } ngx_http_v2_loc_conf_t;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202009191938.08JJchdP035757>