[master] 18e425b Keep the H2 rx window open.
Poul-Henning Kamp
phk at FreeBSD.org
Mon Mar 13 11:38:05 CET 2017
commit 18e425b49888bd23dcea7998d07bb8737f9d7396
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Mar 13 10:37:03 2017 +0000
Keep the H2 rx window open.
diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h
index a3862e5..89b85df 100644
--- a/bin/varnishd/http2/cache_http2.h
+++ b/bin/varnishd/http2/cache_http2.h
@@ -120,7 +120,8 @@ struct h2_req {
struct h2_sess *h2sess;
struct req *req;
VTAILQ_ENTRY(h2_req) list;
- int64_t window;
+ int64_t t_window;
+ int64_t r_window;
struct h2h_decode *decode;
/* Where to wake this stream up */
@@ -139,6 +140,9 @@ struct h2_sess {
struct h2_req *mailcall;
pthread_cond_t *cond;
+ int64_t r_window;
+ int64_t t_window;
+
struct sess *sess;
int refcnt;
uint32_t highest_stream;
diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c
index d1070b3..fb7bfd1 100644
--- a/bin/varnishd/http2/cache_http2_proto.c
+++ b/bin/varnishd/http2/cache_http2_proto.c
@@ -149,6 +149,8 @@ h2_new_req(const struct worker *wrk, struct h2_sess *h2,
r2->h2sess = h2;
r2->stream = stream;
r2->req = req;
+ r2->r_window = h2->local_settings.initial_window_size;
+ r2->t_window = h2->remote_settings.initial_window_size;
req->transport_priv = r2;
Lck_Lock(&h2->sess->mtx);
VTAILQ_INSERT_TAIL(&h2->streams, r2, list);
@@ -314,9 +316,9 @@ h2_rx_window_update(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
if (r2 == NULL)
return (0);
Lck_Lock(&h2->sess->mtx);
- r2->window += wu;
+ r2->t_window += wu;
Lck_Unlock(&h2->sess->mtx);
- if (r2->window >= (1LLU << 31))
+ if (r2->t_window >= (1LLU << 31))
return (H2SE_FLOW_CONTROL_ERROR);
return (0);
}
@@ -558,14 +560,40 @@ h2_rx_continuation(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
static h2_error __match_proto__(h2_frame_f)
h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
{
+ int w1 = 0, w2 = 0;
+ char buf[4];
+ unsigned wi;
+
(void)wrk;
AZ(h2->mailcall);
h2->mailcall = r2;
Lck_Lock(&h2->sess->mtx);
+ h2->r_window -= h2->rxf_len;
+ r2->r_window -= h2->rxf_len;
AZ(pthread_cond_broadcast(h2->cond));
while (h2->mailcall != NULL && h2->error == 0 && r2->error == 0)
AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0));
+ wi = cache_param->h2_rx_window_increment;
+ if (h2->r_window < cache_param->h2_rx_window_low_water) {
+ h2->r_window += wi;
+ w1 = 1;
+ }
+ if (r2->r_window < cache_param->h2_rx_window_low_water) {
+ r2->r_window += wi;
+ w2 = 1;
+ }
Lck_Unlock(&h2->sess->mtx);
+ if (w1 || w2) {
+ vbe32enc(buf, wi);
+ H2_Send_Get(wrk, h2, r2);
+ if (w1)
+ H2_Send_Frame(wrk, h2, H2_F_WINDOW_UPDATE, 0,
+ 4, 0, buf);
+ if (w2)
+ H2_Send_Frame(wrk, h2, H2_F_WINDOW_UPDATE, 0,
+ 4, r2->stream, buf);
+ H2_Send_Rel(h2, r2);
+ }
return (0);
}
diff --git a/bin/varnishtest/tests/t02005.vtc b/bin/varnishtest/tests/t02005.vtc
index 55647ff..2cf31ee 100644
--- a/bin/varnishtest/tests/t02005.vtc
+++ b/bin/varnishtest/tests/t02005.vtc
@@ -12,6 +12,7 @@ client c1 {
stream 1 {
txreq -req POST -hdr content-type text/plain -hdr content-length 7 -body request
+ rxwinup
# First, HTTP checks
rxresp
expect resp.http.content-Type == "text/plain"
diff --git a/bin/varnishtest/tests/t02006.vtc b/bin/varnishtest/tests/t02006.vtc
index 44a9c89..c95feb0 100644
--- a/bin/varnishtest/tests/t02006.vtc
+++ b/bin/varnishtest/tests/t02006.vtc
@@ -27,6 +27,7 @@ client c1 {
rxhdrs
expect resp.status == 100
+ rxwinup
rxresp
expect resp.status == 200
expect resp.http.content-Type == "text/plain"
diff --git a/bin/varnishtest/tests/t02007.vtc b/bin/varnishtest/tests/t02007.vtc
index b0e329e..e9068da 100644
--- a/bin/varnishtest/tests/t02007.vtc
+++ b/bin/varnishtest/tests/t02007.vtc
@@ -32,6 +32,7 @@ client c1 {
rxhdrs
expect resp.status == 100
+ rxwinup
rxresp
expect resp.status == 200
expect resp.http.content-Type == "text/plain"
diff --git a/bin/varnishtest/tests/t02009.vtc b/bin/varnishtest/tests/t02009.vtc
index 2dc1cde..511f54f 100644
--- a/bin/varnishtest/tests/t02009.vtc
+++ b/bin/varnishtest/tests/t02009.vtc
@@ -15,14 +15,14 @@ varnish v1 -cliok "param.set debug +syncvsl"
client c1 {
stream 1 {
- txreq
+ txreq
rxresp
expect resp.http.content-Type == "text/plain"
expect resp.body == response
} -start
stream 5 {
barrier b1 sync
- txreq
+ txreq
rxresp
expect resp.http.content-Type == "text/plain"
expect resp.body == response
diff --git a/include/tbl/h2_settings.h b/include/tbl/h2_settings.h
index 765ee18..7214bef 100644
--- a/include/tbl/h2_settings.h
+++ b/include/tbl/h2_settings.h
@@ -42,7 +42,7 @@ H2_SETTING( // rfc7540,l,2097,2103
HEADER_TABLE_SIZE,
header_table_size,
0x1,
- 4096,
+ 4096, // rfc7540,l,4224,4224
0,
0xffffffff,
0
@@ -51,7 +51,7 @@ H2_SETTING( // rfc7540,l,2105,2114
ENABLE_PUSH,
enable_push,
0x2,
- 1,
+ 1, // rfc7540,l,4225,4225
0,
1,
H2CE_PROTOCOL_ERROR
@@ -60,7 +60,7 @@ H2_SETTING( // rfc7540,l,2116,2121
MAX_CONCURRENT_STREAMS,
max_concurrent_streams,
0x3,
- 0xffffffff,
+ 0xffffffff, // rfc7540,l,4226,4226
0,
0xffffffff,
0
@@ -69,7 +69,7 @@ H2_SETTING( // rfc7540,l,2139,2148
INITIAL_WINDOW_SIZE,
initial_window_size,
0x4,
- 65535,
+ 65535, // rfc7540,l,4227,4227
0,
0x7fffffff,
H2CE_FLOW_CONTROL_ERROR
@@ -78,7 +78,7 @@ H2_SETTING( // rfc7540,l,2150,2157
MAX_FRAME_SIZE,
max_frame_size,
0x5,
- 16384,
+ 16384, // rfc7540,l,4228,4228
16384,
0x00ffffff,
H2CE_PROTOCOL_ERROR
@@ -87,7 +87,7 @@ H2_SETTING( // rfc7540,l,2159,2167
MAX_HEADER_LIST_SIZE,
max_header_list_size,
0x6,
- 0xffffffff,
+ 0xffffffff, // rfc7540,l,4229,4229
0,
0xffffffff,
0
diff --git a/include/tbl/params.h b/include/tbl/params.h
index 49f77ac..cc12632 100644
--- a/include/tbl/params.h
+++ b/include/tbl/params.h
@@ -1651,6 +1651,38 @@ PARAM(
/* func */ NULL
)
+PARAM(
+ /* name */ h2_rx_window_low_water,
+ /* typ */ bytes_u,
+ /* min */ "65535",
+ /* max */ "1G",
+ /* default */ "10M",
+ /* units */ "bytes",
+ /* flags */ WIZARD,
+ /* s-text */
+ "HTTP2 Receive Window low water mark.\n"
+ "We try to keep the window at least this big\n"
+ "Only affects incoming request bodies (ie: POST, PUT etc.)",
+ /* l-text */ "",
+ /* func */ NULL
+)
+
+PARAM(
+ /* name */ h2_rx_window_increment,
+ /* typ */ bytes_u,
+ /* min */ "1M",
+ /* max */ "1G",
+ /* default */ "1M",
+ /* units */ "bytes",
+ /* flags */ WIZARD,
+ /* s-text */
+ "HTTP2 Receive Window Increments.\n"
+ "How big credits we send in WINDOW_UPDATE frames\n"
+ "Only affects incoming request bodies (ie: POST, PUT etc.)",
+ /* l-text */ "",
+ /* func */ NULL
+)
+
#undef PARAM
/*lint -restore */
diff --git a/include/vrt.h b/include/vrt.h
index 34da0ac..2a0f6f2 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -68,7 +68,7 @@
#ifdef __v_printflike
# define __vrt_printflike(a,b) __v_printflike(a,b)
#else
-# define __vrt_printflike(a,b)
+# define __vrt_printflike(a,b)
#endif
struct VCL_conf;
More information about the varnish-commit
mailing list