[PATCH 1/2] Change the TryLock-or-fail behavior of the exp_timer() to TryLock-or-tryharder.

Martin Blix Grydeland martin at varnish-software.com
Thu Apr 19 16:01:39 CEST 2012


On very busy systems, the exp_timer can start to lag behind on it's
work if it frequently fails to acquire the LRU lock out of locking
order. Change this to go the long route when the TryLock fails, and
punt only if the head of the heap has changed while releasing the
locks.
---
 bin/varnishd/cache/cache_expire.c |   18 ++++++++++++------
 1 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/bin/varnishd/cache/cache_expire.c b/bin/varnishd/cache/cache_expire.c
index 39ded77..edbd52c 100644
--- a/bin/varnishd/cache/cache_expire.c
+++ b/bin/varnishd/cache/cache_expire.c
@@ -371,18 +371,24 @@ exp_timer(struct worker *wrk, void *priv)
 
 		/*
 		 * It's time...
-		 * Technically we should drop the exp_mtx, get the lru->mtx
-		 * get the exp_mtx again and then check that the oc is still
-		 * on the binheap.  We take the shorter route and try to
-		 * get the lru->mtx and punt if we fail.
+		 * Try to acquire the lru->mtx. If fail, take the long route
+		 * of releasing the lru->mtx and then getting exp_mtx and
+		 * lru->mtx in the correct order, checking that the oc is
+		 * still head of the heap.
 		 */
 
 		lru = oc_getlru(oc);
 		CHECK_OBJ_NOTNULL(lru, LRU_MAGIC);
 		if (Lck_Trylock(&lru->mtx)) {
 			Lck_Unlock(&exp_mtx);
-			oc = NULL;
-			continue;
+
+			Lck_Lock(&lru->mtx);
+			Lck_Lock(&exp_mtx);
+			if (oc != binheap_root(exp_heap)) {
+				Lck_Unlock(&exp_mtx);
+				Lck_Unlock(&lru->mtx);
+				continue;
+			}
 		}
 
 		/* Remove from binheap */
-- 
1.7.4.1




More information about the varnish-dev mailing list