[master] 5cc47ea Finally fix #2495

Poul-Henning Kamp phk at FreeBSD.org
Mon Feb 19 10:35:08 UTC 2018


commit 5cc47eaa8a174d6f072c68d996ff17b38ccd16eb
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Feb 19 10:30:28 2018 +0000

    Finally fix #2495

diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index 5a0b544..e62e6c9 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -63,7 +63,6 @@
 #include "hash/hash_slinger.h"
 
 #include "vsha256.h"
-#include "vtim.h"
 
 struct rush {
 	unsigned		magic;
diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c
index 9109f9b..edb9907 100644
--- a/bin/varnishd/http1/cache_http1_fsm.c
+++ b/bin/varnishd/http1/cache_http1_fsm.c
@@ -178,6 +178,51 @@ http1_req_fail(struct req *req, enum sess_close reason)
 		SES_Close(req->sp, reason);
 }
 
+/*----------------------------------------------------------------------
+ */
+
+static int
+http1_req_cleanup(struct sess *sp, struct worker *wrk, struct req *req)
+{
+	AZ(wrk->aws->r);
+	AZ(req->ws->r);
+	Req_Cleanup(sp, wrk, req);
+
+	if (sp->fd >= 0 && req->doclose != SC_NULL)
+		SES_Close(sp, req->doclose);
+
+	if (sp->fd < 0) {
+		wrk->stats->sess_closed++;
+		AZ(req->vcl);
+		Req_Release(req);
+		SES_Delete(sp, SC_NULL, NAN);
+		return (1);
+	}
+
+	return (0);
+}
+
+/*----------------------------------------------------------------------
+ * Clean up a req from waiting list which cannot complete
+ */
+
+static void
+http1_cleanup_waiting(struct worker *wrk, struct req *req,
+    enum sess_close reason)
+{
+	struct sess *sp;
+
+	sp = req->sp;
+	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+	AN(req->ws->r);
+	WS_Release(req->ws, 0);
+	AN(req->hash_objhead);
+	(void)HSH_DerefObjHead(wrk, &req->hash_objhead);
+	AZ(req->hash_objhead);
+	SES_Close(sp, reason);
+	AN(http1_req_cleanup(sp, wrk, req));
+}
+
 static void v_matchproto_(vtr_reembark_f)
 http1_reembark(struct worker *wrk, struct req *req)
 {
@@ -188,19 +233,15 @@ http1_reembark(struct worker *wrk, struct req *req)
 
 	http1_setstate(sp, H1BUSY);
 
-	if (!SES_Reschedule_Req(req, TASK_QUEUE_REQ))
+	if (!DO_DEBUG(DBG_FAILRESCHED) &&
+	    !SES_Reschedule_Req(req, TASK_QUEUE_REQ))
 		return;
 
 	/* Couldn't schedule, ditch */
 	wrk->stats->busy_wakeup--;
 	wrk->stats->busy_killed++;
-	AN (req->vcl);
-	VCL_Rel(&req->vcl);
-	Req_AcctLogCharge(wrk->stats, req);
-	Req_Release(req);
-	SES_Delete(sp, SC_OVERLOAD, NAN);
-	DSL(DBG_WAITINGLIST, req->vsl->wid, "kill from waiting list");
-	usleep(10000);
+	VSLb(req->vsl, SLT_Error, "Fail to reschedule req from waiting list");
+	http1_cleanup_waiting(wrk, req, SC_OVERLOAD);
 }
 
 static int v_matchproto_(vtr_minimal_response_f)
@@ -327,30 +368,6 @@ http1_dissect(struct worker *wrk, struct req *req)
 /*----------------------------------------------------------------------
  */
 
-static int
-http1_req_cleanup(struct sess *sp, struct worker *wrk, struct req *req)
-{
-	AZ(wrk->aws->r);
-	AZ(req->ws->r);
-	Req_Cleanup(sp, wrk, req);
-
-	if (sp->fd >= 0 && req->doclose != SC_NULL)
-		SES_Close(sp, req->doclose);
-
-	if (sp->fd < 0) {
-		wrk->stats->sess_closed++;
-		AZ(req->vcl);
-		Req_Release(req);
-		SES_Delete(sp, SC_NULL, NAN);
-		return (1);
-	}
-
-	return (0);
-}
-
-/*----------------------------------------------------------------------
- */
-
 static void
 HTTP1_Session(struct worker *wrk, struct req *req)
 {
@@ -477,13 +494,7 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 			 * Check to see if the remote has left.
 			 */
 			if (VTCP_check_hup(sp->fd)) {
-				AN(req->ws->r);
-				WS_Release(req->ws, 0);
-				AN(req->hash_objhead);
-				(void)HSH_DerefObjHead(wrk, &req->hash_objhead);
-				AZ(req->hash_objhead);
-				SES_Close(sp, SC_REM_CLOSE);
-				AN(http1_req_cleanup(sp, wrk, req));
+				http1_cleanup_waiting(wrk, req, SC_REM_CLOSE);
 				return;
 			}
 			http1_setstate(sp, H1PROC);
diff --git a/bin/varnishtest/tests/c00013.vtc b/bin/varnishtest/tests/c00013.vtc
index e2bbedb..1fcccac 100644
--- a/bin/varnishtest/tests/c00013.vtc
+++ b/bin/varnishtest/tests/c00013.vtc
@@ -46,5 +46,64 @@ client c2 {
 
 client c1 -wait
 
+varnish v1 -vsl_catchup
 varnish v1 -expect busy_sleep >= 1
 varnish v1 -expect busy_wakeup >= 1
+varnish v1 -stop
+
+##################################################
+# Now try again where getting a thread fails
+
+barrier b3 cond 2
+barrier b4 cond 2
+
+server s3 {
+	rxreq
+	expect req.url == "/foo"
+	send "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n"
+	delay .2
+	barrier b3 sync
+	delay .2
+	send "line1\n"
+	delay .2
+	barrier b4 sync
+	send "line2\n"
+} -start
+
+varnish v3 -vcl+backend {
+	sub vcl_backend_fetch {
+		set bereq.backend = s3;
+	}
+	sub vcl_backend_response {
+		set beresp.do_stream = false;
+	}
+} -start
+
+varnish v3 -cliok "param.set debug +failresched"
+
+varnish v3 -cliok "param.set debug +syncvsl"
+
+client c3 -connect ${v3_sock} {
+	txreq -url "/foo" -hdr "client: c3"
+	rxresp
+	expect resp.status == 200
+	expect resp.bodylen == 12
+	expect resp.http.x-varnish == "1001"
+} -start
+
+barrier b3 sync
+
+client c4 -connect ${v3_sock} {
+	txreq -url "/foo" -hdr "client: c4"
+	delay .2
+	barrier b4 sync
+	expect_close
+} -run
+
+client c3 -wait
+
+varnish v1 -vsl_catchup
+varnish v3 -expect busy_sleep >= 1
+varnish v3 -expect busy_wakeup == 0
+varnish v3 -expect busy_killed == 1
+varnish v3 -expect sc_overload == 1
diff --git a/include/tbl/debug_bits.h b/include/tbl/debug_bits.h
index 4ac3ef6..b451f33 100644
--- a/include/tbl/debug_bits.h
+++ b/include/tbl/debug_bits.h
@@ -50,6 +50,7 @@ DEBUG_BIT(H2_NOCHECK,		h2_nocheck,	"Disable various H2 checks")
 DEBUG_BIT(VMOD_SO_KEEP,		vmod_so_keep,	"Keep copied VMOD libraries")
 DEBUG_BIT(PROCESSORS,		processors,	"Fetch/Deliver processors")
 DEBUG_BIT(PROTOCOL,		protocol,	"Protocol debugging")
+DEBUG_BIT(FAILRESCHED,		failresched,	"Fail from waiting list")
 #undef DEBUG_BIT
 
 /*lint -restore */


More information about the varnish-commit mailing list