[master] 3694a418f Push pool stats to global stats on delayed VCL release

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Mon Jan 11 17:06:07 UTC 2021


commit 3694a418f1234bb0b8196676ab4cf1698a152343
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Thu May 14 14:18:40 2020 +0200

    Push pool stats to global stats on delayed VCL release
    
    Often in test cases the siutation comes where multiple threads go idle at
    the same time, and no new activity happens after that. This would
    potentially create the situation where the last thread to go idle sees
    that some thread is currently pushing stats to global, so it leaves its
    stats contribution on the pool stats to avoid contention. But without new
    activity in the future, the pool stats may stay in the pool accumulator
    indefinitely.
    
    This patch adds a check to see if there are unaccumulated statistics
    lingering in the pool accumulator when a thread wakes after idling to
    release its VCL reference. If there are, the thread takes on the task of
    pushing the pool stats to the global stats. This should help with test
    case stability, and potentially help with underflowed stats reported by
    some users.

diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c
index 39e4b4361..b7b31296c 100644
--- a/bin/varnishd/cache/cache_wrk.c
+++ b/bin/varnishd/cache/cache_wrk.c
@@ -398,10 +398,32 @@ Pool_Work_Thread(struct pool *pp, struct worker *wrk)
 				i = Lck_CondWait(&wrk->cond, &pp->mtx, tmo);
 				if (i == ETIMEDOUT)
 					VCL_Rel(&wrk->vcl);
-			} while (wrk->task->func == NULL);
-			tpx = *wrk->task;
-			tp = &tpx;
-			wrk->stats->summs++;
+				if (wrk->task->func != NULL) {
+					/* We have been handed a new task */
+					tpx = *wrk->task;
+					tp = &tpx;
+					wrk->stats->summs++;
+				} else if (pp->b_stat != NULL &&
+				    pp->a_stat->summs) {
+					/* Woken up to release the VCL,
+					 * and noticing that there are
+					 * pool stats not pushed to the
+					 * global stats and no active
+					 * thread currently doing
+					 * it. Remove ourself from the
+					 * idle queue and take on the
+					 * task. */
+					assert(pp->nidle > 0);
+					VTAILQ_REMOVE(&pp->idle_queue,
+					    wrk->task, list);
+					pp->nidle--;
+					tps.func = pool_stat_summ;
+					tps.priv = pp->a_stat;
+					pp->a_stat = pp->b_stat;
+					pp->b_stat = NULL;
+					tp = &tps;
+				}
+			} while (tp == NULL);
 		}
 		Lck_Unlock(&pp->mtx);
 


More information about the varnish-commit mailing list