[master] 91d77ac Modify the ban_lurker so we lift oc's as far up the ban-list as we can when we check a batch of lurkable bans.

Poul-Henning Kamp phk at FreeBSD.org
Tue Nov 10 11:54:10 CET 2015


commit 91d77ac75fba9e8240966ce3e52771118e92b3a0
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Nov 10 10:52:01 2015 +0000

    Modify the ban_lurker so we lift oc's as far up the ban-list as we
    can when we check a batch of lurkable bans.
    
    For obj.* only bans, this should concentrate the entire list at the
    very top.
    
    If there are req.* bans, the oc's end up on the bans right below
    the req.* bans.
    
    Fixes	#1635
    
    (As much as we can fix it)

diff --git a/bin/varnishd/cache/cache_ban.c b/bin/varnishd/cache/cache_ban.c
index 3bf9073..c8971bc 100644
--- a/bin/varnishd/cache/cache_ban.c
+++ b/bin/varnishd/cache/cache_ban.c
@@ -159,14 +159,16 @@ ban_mark_completed(struct ban *b)
 	Lck_AssertHeld(&ban_mtx);
 
 	AN(b->spec);
-	AZ(b->flags & BANS_FLAG_COMPLETED);
-	ln = ban_len(b->spec);
-	b->flags |= BANS_FLAG_COMPLETED;
-	b->spec[BANS_FLAGS] |= BANS_FLAG_COMPLETED;
-	VWMB();
-	vbe32enc(b->spec + BANS_LENGTH, BANS_HEAD_LEN);
-	VSC_C_main->bans_completed++;
-	VSC_C_main->bans_persisted_fragmentation += ln - ban_len(b->spec);
+	if (!(b->flags & BANS_FLAG_COMPLETED)) {
+		ln = ban_len(b->spec);
+		b->flags |= BANS_FLAG_COMPLETED;
+		b->spec[BANS_FLAGS] |= BANS_FLAG_COMPLETED;
+		VWMB();
+		vbe32enc(b->spec + BANS_LENGTH, BANS_HEAD_LEN);
+		VSC_C_main->bans_completed++;
+		VSC_C_main->bans_persisted_fragmentation +=
+		    ln - ban_len(b->spec);
+	}
 }
 
 /*--------------------------------------------------------------------
@@ -683,7 +685,7 @@ ccf_ban_list(struct cli *cli, const char * const *av, void *priv)
 		o = bl == b ? 1 : 0;
 		VCLI_Out(cli, "%10.6f %5ju %s", ban_time(b->spec),
 		    (intmax_t)b->refcount - o,
-		    b->flags & BANS_FLAG_COMPLETED ? "C" : " ");
+		    b->flags & BANS_FLAG_COMPLETED ? "C" : "-");
 		if (DO_DEBUG(DBG_LURKER)) {
 			VCLI_Out(cli, "%s%s %p ",
 			    b->flags & BANS_FLAG_REQ ? "R" : "-",
diff --git a/bin/varnishd/cache/cache_ban_lurker.c b/bin/varnishd/cache/cache_ban_lurker.c
index 352b219..63371f8 100644
--- a/bin/varnishd/cache/cache_ban_lurker.c
+++ b/bin/varnishd/cache/cache_ban_lurker.c
@@ -112,7 +112,9 @@ ban_lurker_getfirst(struct vsl_log *vsl, struct ban *bt)
 			} else {
 				/*
 				 * We got the lock, and the oc is not being
-				 * dismantled under our feet, run with it...
+				 * dismantled under our feet.
+				 * Take it off the ban and (optimistically)
+				 * put it on the * destination ban
 				 */
 				AZ(oc->flags & OC_F_BUSY);
 				oc->refcnt += 1;
@@ -135,7 +137,7 @@ ban_lurker_getfirst(struct vsl_log *vsl, struct ban *bt)
 
 static void
 ban_lurker_test_ban(struct worker *wrk, struct vsl_log *vsl, struct ban *bt,
-    struct banhead_s *obans)
+    struct banhead_s *obans, struct ban *bd)
 {
 	struct ban *bl, *bln;
 	struct objcore *oc;
@@ -182,6 +184,17 @@ ban_lurker_test_ban(struct worker *wrk, struct vsl_log *vsl, struct ban *bt,
 			EXP_Rearm(oc, oc->exp.t_origin, 0, 0, 0);
 					// XXX ^ fake now
 			VSC_C_main->bans_lurker_obj_killed++;
+		} else {
+			if (oc->ban != bd) {
+				Lck_Lock(&ban_mtx);
+				oc->ban->refcount--;
+				VTAILQ_REMOVE(&oc->ban->objcore, oc, ban_list);
+				oc->ban = bd;
+				bd->refcount++;
+				VTAILQ_INSERT_TAIL(&bd->objcore, oc, ban_list);
+				Lck_Unlock(&ban_mtx);
+				ObjUpdateMeta(wrk, oc);
+			}
 		}
 		(void)HSH_DerefObjCore(wrk, &oc);
 	}
@@ -194,63 +207,43 @@ ban_lurker_test_ban(struct worker *wrk, struct vsl_log *vsl, struct ban *bt,
 static double
 ban_lurker_work(struct worker *wrk, struct vsl_log *vsl)
 {
-	struct ban *b, *bt;
+	struct ban *b, *bd;
 	struct banhead_s obans;
 	double d, dt, n;
-	int i;
 
 	dt = 49.62;		// Random, non-magic
 	if (cache_param->ban_lurker_sleep == 0)
 		return (dt);
-	/* Make a list of the bans we can do something about */
-	VTAILQ_INIT(&obans);
+
 	Lck_Lock(&ban_mtx);
 	b = ban_start;
 	Lck_Unlock(&ban_mtx);
-	i = 0;
 	d = VTIM_real() - cache_param->ban_lurker_age;
+	bd = NULL;
+	VTAILQ_INIT(&obans);
 	for (; b != NULL; b = VTAILQ_NEXT(b, list)) {
+		if (bd != NULL)
+			ban_lurker_test_ban(wrk, vsl, b, &obans, bd);
 		if (b->flags & BANS_FLAG_COMPLETED)
 			continue;
-		if (b->flags & BANS_FLAG_REQ)
+		if (b->flags & BANS_FLAG_REQ) {
+			bd = VTAILQ_NEXT(b, list);
 			continue;
-		if (b == VTAILQ_LAST(&ban_head, banhead_s))
-			continue;	// XXX: why ?
+		}
 		n = ban_time(b->spec) - d;
 		if (n < 0) {
 			VTAILQ_INSERT_TAIL(&obans, b, l_list);
-			i++;
+			if (bd == NULL)
+				bd = b;
 		} else if (n < dt) {
 			dt = n;
 		}
 	}
-	if (DO_DEBUG(DBG_LURKER))
-		VSLb(vsl, SLT_Debug, "lurker: %d actionable bans, dt = %lf", i, dt);
-	if (i == 0)
-		return (dt);
 
-	dt = cache_param->ban_lurker_sleep;
-	/* Go though all the bans to test the objects */
-	VTAILQ_FOREACH_REVERSE(bt, &ban_head, banhead_s, list) {
-		if (bt == VTAILQ_LAST(&obans, banhead_s)) {
-			if (DO_DEBUG(DBG_LURKER))
-				VSLb(vsl, SLT_Debug,
-				    "Lurk bt completed %p", bt);
-			Lck_Lock(&ban_mtx);
-			/* We can be raced by a new ban */
-			if (!(bt->flags & BANS_FLAG_COMPLETED))
-				ban_mark_completed(bt);
-			Lck_Unlock(&ban_mtx);
-			VTAILQ_REMOVE(&obans, bt, l_list);
-			if (VTAILQ_EMPTY(&obans))
-				break;
-		}
-		if (DO_DEBUG(DBG_LURKER))
-			VSLb(vsl, SLT_Debug, "Lurk bt %p", bt);
-		ban_lurker_test_ban(wrk, vsl, bt, &obans);
-		if (VTAILQ_EMPTY(&obans))
-			break;
-	}
+	Lck_Lock(&ban_mtx);
+	VTAILQ_FOREACH(b, &obans, l_list)
+		ban_mark_completed(b);
+	Lck_Unlock(&ban_mtx);
 	return (dt);
 }
 
@@ -268,9 +261,9 @@ ban_lurker(struct worker *wrk, void *priv)
 
 	while (!ban_shutdown) {
 		d = ban_lurker_work(wrk, &vsl);
+		ban_cleantail();
 		if (DO_DEBUG(DBG_LURKER))
 			VSLb(&vsl, SLT_Debug, "lurker: sleep = %lf", d);
-		ban_cleantail();
 		d += VTIM_real();
 		Lck_Lock(&ban_mtx);
 		if (gen == ban_generation) {
diff --git a/bin/varnishtest/tests/c00049.vtc b/bin/varnishtest/tests/c00049.vtc
index 8d10e68..e86c513 100644
--- a/bin/varnishtest/tests/c00049.vtc
+++ b/bin/varnishtest/tests/c00049.vtc
@@ -94,7 +94,7 @@ client c1 {
 } -run
 
 # Get the VSL out of the way
-delay .1
+delay 1
 
 varnish v1 -cliok "ban.list"
 
@@ -115,18 +115,20 @@ varnish v1 -expect bans_dups == 0
 
 varnish v1 -cliok "param.set ban_lurker_sleep .01"
 
+delay 1
+
 varnish v1 -cliok "ban.list"
 
-delay 2
+delay 1
 
 varnish v1 -cliok "ban.list"
 
-varnish v1 -expect bans == 5
-varnish v1 -expect bans_completed == 4
+varnish v1 -expect bans == 4
+varnish v1 -expect bans_completed == 3
 varnish v1 -expect bans_req == 1
-varnish v1 -expect bans_obj == 4
+varnish v1 -expect bans_obj == 3
 varnish v1 -expect bans_added == 6
-varnish v1 -expect bans_deleted == 1
+varnish v1 -expect bans_deleted == 2
 varnish v1 -expect bans_tested == 0
 varnish v1 -expect bans_tests_tested == 0
 varnish v1 -expect bans_obj_killed == 0



More information about the varnish-commit mailing list