[master] fd4a927 Add extra locking to protect the pools list and refcounts

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Mon Jul 3 12:55:06 CEST 2017


commit fd4a9271f887e1568ba333b20699d65af9ebc07a
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Tue Jun 27 15:33:41 2017 +0200

    Add extra locking to protect the pools list and refcounts
    
    Probes currently running on a worker thread at the time they are
    deleted will delay the release of the refcount they hold on the TCP
    pool. Since this call will not be from the CLI thread we need locking
    to protect these datastructures.

diff --git a/bin/varnishd/cache/cache_backend_tcp.c b/bin/varnishd/cache/cache_backend_tcp.c
index 681834f..8f8a772 100644
--- a/bin/varnishd/cache/cache_backend_tcp.c
+++ b/bin/varnishd/cache/cache_backend_tcp.c
@@ -69,6 +69,7 @@ struct tcp_pool {
 
 };
 
+static struct lock		pools_mtx;
 static VTAILQ_HEAD(, tcp_pool)	pools = VTAILQ_HEAD_INITIALIZER(pools);
 
 /*--------------------------------------------------------------------
@@ -125,6 +126,7 @@ VBT_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6)
 {
 	struct tcp_pool *tp;
 
+	Lck_Lock(&pools_mtx);
 	VTAILQ_FOREACH(tp, &pools, list) {
 		assert(tp->refcnt > 0);
 		if (ip4 == NULL) {
@@ -146,8 +148,10 @@ VBT_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6)
 				continue;
 		}
 		tp->refcnt++;
+		Lck_Unlock(&pools_mtx);
 		return (tp);
 	}
+	Lck_Unlock(&pools_mtx);
 
 	ALLOC_OBJ(tp, TCP_POOL_MAGIC);
 	AN(tp);
@@ -159,7 +163,11 @@ VBT_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6)
 	Lck_New(&tp->mtx, lck_backend_tcp);
 	VTAILQ_INIT(&tp->connlist);
 	VTAILQ_INIT(&tp->killlist);
+
+	Lck_Lock(&pools_mtx);
 	VTAILQ_INSERT_HEAD(&pools, tp, list);
+	Lck_Unlock(&pools_mtx);
+
 	return (tp);
 }
 
@@ -174,11 +182,17 @@ VBT_Rel(struct tcp_pool **tpp)
 	struct vbc *vbc, *vbc2;
 
 	TAKE_OBJ_NOTNULL(tp, tpp, TCP_POOL_MAGIC);
+
+	Lck_Lock(&pools_mtx);
 	assert(tp->refcnt > 0);
-	if (--tp->refcnt > 0)
+	if (--tp->refcnt > 0) {
+		Lck_Unlock(&pools_mtx);
 		return;
+	}
 	AZ(tp->n_used);
 	VTAILQ_REMOVE(&pools, tp, list);
+	Lck_Unlock(&pools_mtx);
+
 	free(tp->name);
 	free(tp->ip4);
 	free(tp->ip6);
@@ -400,3 +414,11 @@ VBT_Wait(struct worker *wrk, struct vbc *vbc)
 	vbc->cond = NULL;
 	Lck_Unlock(&tp->mtx);
 }
+
+/*--------------------------------------------------------------------*/
+
+void
+VBT_Init(void)
+{
+	Lck_New(&pools_mtx, lck_backend);
+}
diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c
index 1467706..d6c8921 100644
--- a/bin/varnishd/cache/cache_main.c
+++ b/bin/varnishd/cache/cache_main.c
@@ -238,6 +238,7 @@ child_main(void)
 	HTTP_Init();
 
 	VBO_Init();
+	VBT_Init();
 	VBP_Init();
 	VBE_InitCfg();
 	Pool_Init();
diff --git a/bin/varnishd/cache/cache_priv.h b/bin/varnishd/cache/cache_priv.h
index 215ebc9..66071b9 100644
--- a/bin/varnishd/cache/cache_priv.h
+++ b/bin/varnishd/cache/cache_priv.h
@@ -41,6 +41,9 @@ void VCA_Shutdown(void);
 void VBE_InitCfg(void);
 void VBE_Poll(void);
 
+/* cache_backend_tcp.c */
+void VBT_Init(void);
+
 /* cache_backend_poll.c */
 void VBP_Init(void);
 



More information about the varnish-commit mailing list