[master] 1502d90 Handle races with lookup more efficiently

Nils Goroll nils.goroll at uplex.de
Tue May 3 16:31:06 CEST 2016


commit 1502d90e901b36b9e49a4d0b252c9b9c1ffff2d3
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Tue Apr 26 14:01:47 2016 +0200

    Handle races with lookup more efficiently
    
    The ban lurker checks bans concurrently to lookup. Lookup checks are better
    informed then ban lurker checks, in particular because they have access
    to request information and can thus check request bans.
    
    So, do not touch ocs which were moved concurrent to the ban lurker working them.
    
    Unprotected access to oc->ban may be outdated, so re-check under the ban_mtx.
    
    Idea for great simplification by
    Martin Blix Grydeland <martin at varnish-software.com>

diff --git a/bin/varnishd/cache/cache_ban_lurker.c b/bin/varnishd/cache/cache_ban_lurker.c
index 1c3dfbe..9930b98 100644
--- a/bin/varnishd/cache/cache_ban_lurker.c
+++ b/bin/varnishd/cache/cache_ban_lurker.c
@@ -178,6 +178,14 @@ ban_lurker_test_ban(struct worker *wrk, struct vsl_log *vsl, struct ban *bt,
 			VSC_C_main->bans_lurker_tests_tested += tests;
 			if (i)
 				break;
+			/*
+			 * XXX can we do this? can we safely assert that if
+			 * lookup has raced us it will have moved the oc
+			 * above the olist?
+			 *
+			if (oc->ban != bt)
+				break;
+			*/
 		}
 		if (i) {
 			VSLb(vsl, SLT_ExpBan, "%u banned by lurker",
@@ -186,8 +194,17 @@ ban_lurker_test_ban(struct worker *wrk, struct vsl_log *vsl, struct ban *bt,
 			HSH_Kill(oc);
 			VSC_C_main->bans_lurker_obj_killed++;
 		} else {
-			if (oc->ban != bd) {
+			/*
+			 * we race lookup-time ban checks - oc may have moved up
+			 * the ban list already and we do not want to move it
+			 * down again.
+			 */
+			while (oc->ban == bt) {
 				Lck_Lock(&ban_mtx);
+				if (oc->ban != bt) {
+					Lck_Unlock(&ban_mtx);
+					break;
+				}
 				oc->ban->refcount--;
 				VTAILQ_REMOVE(&oc->ban->objcore, oc, ban_list);
 				oc->ban = bd;
@@ -195,6 +212,7 @@ ban_lurker_test_ban(struct worker *wrk, struct vsl_log *vsl, struct ban *bt,
 				VTAILQ_INSERT_TAIL(&bd->objcore, oc, ban_list);
 				Lck_Unlock(&ban_mtx);
 				ObjSendEvent(wrk, oc, OEV_BANCHG);
+				break;
 			}
 		}
 		(void)HSH_DerefObjCore(wrk, &oc);



More information about the varnish-commit mailing list