[master] 1225301 Ditch the per tcp-pool waiters and recycle backend connections on the pool waiter for the working thread doing the recycling.

Poul-Henning Kamp phk at FreeBSD.org
Wed May 27 23:38:32 CEST 2015


commit 1225301cfe89a682b096b820819256566e9b1c77
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed May 27 21:36:56 2015 +0000

    Ditch the per tcp-pool waiters and recycle backend connections on
    the pool waiter for the working thread doing the recycling.
    
    This does not restrict which threads can reuse the connection later on.

diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index d451943..e84ff06 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -184,7 +184,7 @@ vbe_dir_finish(const struct director *d, struct worker *wrk,
 		    bp->display_name);
 		Lck_Lock(&bp->mtx);
 		VSC_C_main->backend_recycle++;
-		VBT_Recycle(bp->tcp_pool, &bo->htc->vbc);
+		VBT_Recycle(wrk, bp->tcp_pool, &bo->htc->vbc);
 	}
 #define ACCT(foo)	bp->vsc->foo += bo->acct.foo;
 #include "tbl/acct_fields_bereq.h"
diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h
index 7fdc55b..11f14bd 100644
--- a/bin/varnishd/cache/cache_backend.h
+++ b/bin/varnishd/cache/cache_backend.h
@@ -119,7 +119,7 @@ struct tcp_pool *VBT_Ref(const struct suckaddr *ip4,
     const struct suckaddr *ip6);
 void VBT_Rel(struct tcp_pool **tpp);
 int VBT_Open(const struct tcp_pool *tp, double tmo, const struct suckaddr **sa);
-void VBT_Recycle(struct tcp_pool *tp, struct vbc **vbc);
+void VBT_Recycle(const struct worker *, struct tcp_pool *, struct vbc **);
 void VBT_Close(struct tcp_pool *tp, struct vbc **vbc);
 struct vbc *VBT_Get(struct tcp_pool *, double tmo, struct backend *,
     struct worker *);
diff --git a/bin/varnishd/cache/cache_backend_tcp.c b/bin/varnishd/cache/cache_backend_tcp.c
index f130abd..70afa2e 100644
--- a/bin/varnishd/cache/cache_backend_tcp.c
+++ b/bin/varnishd/cache/cache_backend_tcp.c
@@ -39,6 +39,7 @@
 #include "cache.h"
 
 #include "cache_backend.h"
+#include "cache_pool.h"
 #include "vtcp.h"
 #include "vsa.h"
 #include "vtim.h"
@@ -56,7 +57,6 @@ struct tcp_pool {
 	struct lock		mtx;
 
 	struct waitfor		waitfor;
-	struct waiter		*waiter;
 	volatile double		timeout;
 
 	VTAILQ_HEAD(, vbc)	connlist;
@@ -166,7 +166,6 @@ VBT_Ref(const struct suckaddr *ip4, const struct suckaddr *ip6)
 	INIT_OBJ(&tp->waitfor, WAITFOR_MAGIC);
 	tp->waitfor.func = tcp_handle;
 	tp->waitfor.tmo = &tp->timeout;
-	tp->waiter = Waiter_New(&tp->waitfor);
 	return (tp);
 }
 
@@ -211,7 +210,6 @@ VBT_Rel(struct tcp_pool **tpp)
 	Lck_Delete(&tp->mtx);
 	AZ(tp->n_conn);
 	AZ(tp->n_kill);
-	Waiter_Destroy(&tp->waiter);
 
 	FREE_OBJ(tp);
 }
@@ -250,11 +248,12 @@ VBT_Open(const struct tcp_pool *tp, double tmo, const struct suckaddr **sa)
  */
 
 void
-VBT_Recycle(struct tcp_pool *tp, struct vbc **vbcp)
+VBT_Recycle(const struct worker *wrk, struct tcp_pool *tp, struct vbc **vbcp)
 {
 	struct vbc *vbc;
 	int i = 0;
 
+	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(tp, TCP_POOL_MAGIC);
 	vbc = *vbcp;
 	*vbcp = NULL;
@@ -271,7 +270,8 @@ VBT_Recycle(struct tcp_pool *tp, struct vbc **vbcp)
 	vbc->waited->fd = vbc->fd;
 	vbc->waited->idle = VTIM_real();
 	vbc->state = VBC_STATE_AVAIL;
-	if (Wait_Enter(tp->waiter, vbc->waited)) {
+	vbc->waited->waitfor =  &tp->waitfor;
+	if (Wait_Enter(wrk->pool->waiter, vbc->waited)) {
 		VTCP_close(&vbc->fd);
 		memset(vbc, 0x33, sizeof *vbc);
 		free(vbc);
diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index 76d47b8..2d55cba 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -482,6 +482,7 @@ SES_Wait(struct sess *sp)
 	sp->waited.fd = sp->fd;
 	sp->waited.ptr = sp;
 	sp->waited.idle = sp->t_idle;
+	sp->waited.waitfor = &pp->wf;
 	if (Wait_Enter(pp->waiter, &sp->waited))
 		SES_Delete(sp, SC_PIPE_OVERFLOW, NAN);
 }
@@ -587,5 +588,5 @@ SES_NewPool(struct pool *pp, unsigned pool_no)
 	INIT_OBJ(&pp->wf, WAITFOR_MAGIC);
 	pp->wf.func = ses_handle;
 	pp->wf.tmo = &cache_param->timeout_idle;
-	pp->waiter = Waiter_New(&pp->wf);
+	pp->waiter = Waiter_New();
 }
diff --git a/bin/varnishd/waiter/cache_waiter.c b/bin/varnishd/waiter/cache_waiter.c
index 4d2f794..7d23da5 100644
--- a/bin/varnishd/waiter/cache_waiter.c
+++ b/bin/varnishd/waiter/cache_waiter.c
@@ -51,7 +51,7 @@ waited_cmp(void *priv, const void *a, const void *b)
 	CAST_OBJ_NOTNULL(aa, a, WAITED_MAGIC);
 	CAST_OBJ_NOTNULL(bb, b, WAITED_MAGIC);
 
-	return (Wait_When(ww, aa) < Wait_When(ww, bb));
+	return (Wait_When(aa) < Wait_When(bb));
 }
 
 static void __match_proto__(binheap_update_t)
@@ -72,12 +72,12 @@ Wait_Call(const struct waiter *w,
 {
 	CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
 	CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
-	CHECK_OBJ_NOTNULL(w->waitfor, WAITFOR_MAGIC);
-	AN(w->waitfor->func);
+	CHECK_OBJ_NOTNULL(wp->waitfor, WAITFOR_MAGIC);
+	AN(wp->waitfor->func);
 	if (wp->idx != BINHEAP_NOIDX)
 		binheap_delete(w->heap, wp->idx);
 	assert(wp->idx == BINHEAP_NOIDX);
-	w->waitfor->func(wp, ev, now);
+	wp->waitfor->func(wp, ev, now);
 }
 
 /**********************************************************************/
@@ -105,7 +105,7 @@ Wait_HeapDue(const struct waiter *w, struct waited **wpp)
 	}
 	if (wpp != NULL)
 		*wpp = wp;
-	return(Wait_When(w, wp));
+	return(Wait_When(wp));
 }
 
 /**********************************************************************/
@@ -117,6 +117,7 @@ Wait_Enter(const struct waiter *w, struct waited *wp)
 	CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
 	CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
 	assert(wp->fd > 0);			// stdin never comes here
+	CHECK_OBJ_NOTNULL(wp->waitfor, WAITFOR_MAGIC);
 	wp->idx = BINHEAP_NOIDX;
 	return (w->impl->enter(w->priv, wp));
 }
@@ -134,7 +135,7 @@ Waiter_GetName(void)
 }
 
 struct waiter *
-Waiter_New(struct waitfor *wf)
+Waiter_New(void)
 {
 	struct waiter *w;
 
@@ -149,7 +150,6 @@ Waiter_New(struct waitfor *wf)
 	INIT_OBJ(w, WAITER_MAGIC);
 	w->priv = (void*)(w + 1);
 	w->impl = waiter;
-	w->waitfor = wf;
 	VTAILQ_INIT(&w->waithead);
 	w->heap = binheap_new(w, waited_cmp, waited_update);
 
diff --git a/bin/varnishd/waiter/cache_waiter_kqueue.c b/bin/varnishd/waiter/cache_waiter_kqueue.c
index ea5ea22..90ba41d 100644
--- a/bin/varnishd/waiter/cache_waiter_kqueue.c
+++ b/bin/varnishd/waiter/cache_waiter_kqueue.c
@@ -148,7 +148,7 @@ vwk_enter(void *priv, struct waited *wp)
 	AZ(kevent(vwk->kq, &ke, 1, NULL, 0, NULL));
 
 	/* If the kqueue isn't due before our timeout, poke it via the pipe */
-	if (Wait_When(vwk->waiter, wp) < vwk->next)
+	if (Wait_When(wp) < vwk->next)
 		assert(write(vwk->pipe[1], "X", 1) == 1);
 
 	Lck_Unlock(&vwk->mtx);
diff --git a/bin/varnishd/waiter/cache_waiter_poll.c b/bin/varnishd/waiter/cache_waiter_poll.c
index 5c56f9b..471d9e7 100644
--- a/bin/varnishd/waiter/cache_waiter_poll.c
+++ b/bin/varnishd/waiter/cache_waiter_poll.c
@@ -183,7 +183,7 @@ vwp_main(void *priv)
 				break;
 			if (vwp->pollfd[i].revents)
 				v--;
-			then = Wait_When(vwp->waiter, wp);
+			then = Wait_When(wp);
 			if (then <= now) {
 				Wait_Call(vwp->waiter, wp, WAITER_TIMEOUT, now);
 				vwp_del(vwp, i);
diff --git a/bin/varnishd/waiter/waiter.h b/bin/varnishd/waiter/waiter.h
index 7227fcd..3d301ea 100644
--- a/bin/varnishd/waiter/waiter.h
+++ b/bin/varnishd/waiter/waiter.h
@@ -67,12 +67,13 @@ struct waited {
 	int			fd;
 	unsigned		idx;
 	void			*ptr;
+	const struct waitfor	*waitfor;
 	double			idle;
 	VTAILQ_ENTRY(waited)	list;
 };
 
 /* cache_waiter.c */
 int Wait_Enter(const struct waiter *, struct waited *);
-struct waiter *Waiter_New(struct waitfor *);
+struct waiter *Waiter_New(void);
 void Waiter_Destroy(struct waiter **);
 const char *Waiter_GetName(void);
diff --git a/bin/varnishd/waiter/waiter_priv.h b/bin/varnishd/waiter/waiter_priv.h
index 331e3ad..f4e5261 100644
--- a/bin/varnishd/waiter/waiter_priv.h
+++ b/bin/varnishd/waiter/waiter_priv.h
@@ -39,8 +39,6 @@ struct waiter {
 	VTAILQ_ENTRY(waiter)		list;
 	VTAILQ_HEAD(,waited)		waithead;
 
-	struct waitfor			*waitfor;
-
 	void				*priv;
 	struct binheap			*heap;
 };
@@ -61,19 +59,20 @@ struct waiter_impl {
 };
 
 static inline double
-Wait_Tmo(const struct waiter *w, const struct waited *wp)
+Wait_Tmo(const struct waited *wp)
 {
-	CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
 	CHECK_OBJ_ORNULL(wp, WAITED_MAGIC);
-	CHECK_OBJ_NOTNULL(w->waitfor, WAITFOR_MAGIC);
-	AN(w->waitfor->tmo);
-	return (*w->waitfor->tmo);
+	CHECK_OBJ_NOTNULL(wp->waitfor, WAITFOR_MAGIC);
+	AN(wp->waitfor->tmo);
+	return (*wp->waitfor->tmo);
 }
 
 static inline double
-Wait_When(const struct waiter *w, const struct waited *wp)
+Wait_When(const struct waited *wp)
 {
-	return (Wait_Tmo(w, wp) + wp->idle);
+	CHECK_OBJ_ORNULL(wp, WAITED_MAGIC);
+	CHECK_OBJ_NOTNULL(wp->waitfor, WAITFOR_MAGIC);
+	return (wp->idle + *wp->waitfor->tmo);
 }
 
 void Wait_Call(const struct waiter *, struct waited *,



More information about the varnish-commit mailing list