[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