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


_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev

Reply via email to