[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