[experimental-ims] ac1fae5 Screw up the session allocator performance, in order to prepare it for per-pool operation.

Geoff Simmons geoff at varnish-cache.org
Mon Jan 9 21:51:55 CET 2012


commit ac1fae53f4b5c66db6db5d7e3ade181b2ab6dc50
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sat Sep 17 20:06:36 2011 +0000

    Screw up the session allocator performance, in order to prepare it
    for per-pool operation.

diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h
index 6c0c525..71cf6b3 100644
--- a/bin/varnishd/cache.h
+++ b/bin/varnishd/cache.h
@@ -108,6 +108,7 @@ struct objhead;
 struct objcore;
 struct busyobj;
 struct storage;
+struct sesspool;
 struct vrt_backend;
 struct cli_proto;
 struct ban;
@@ -849,7 +850,7 @@ void WRW_Sendfile(struct worker *w, int fd, off_t off, unsigned len);
 
 /* cache_session.c [SES] */
 void SES_Init(void);
-struct sess *SES_New(void);
+struct sess *SES_New(struct sesspool *pp);
 struct sess *SES_Alloc(void);
 void SES_Close(struct sess *sp, const char *reason);
 void SES_Delete(struct sess *sp, const char *reason);
diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c
index 0022037..37cc857 100644
--- a/bin/varnishd/cache_acceptor.c
+++ b/bin/varnishd/cache_acceptor.c
@@ -316,7 +316,7 @@ vca_acct(void *arg)
 			i = VCA_Accept(ls->sock, &l, &addr_s);
 			if (i < 0) 
 				continue;
-			sp = SES_New();
+			sp = SES_New(NULL);
 			if (sp == NULL) {
 				AZ(close(i));
 				VSC_C_main->client_drop++;
diff --git a/bin/varnishd/cache_session.c b/bin/varnishd/cache_session.c
index 15373a4..6b34928 100644
--- a/bin/varnishd/cache_session.c
+++ b/bin/varnishd/cache_session.c
@@ -26,16 +26,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * Session and Client management.
+ * Session management
  *
- * XXX: The two-list session management is actually not a good idea
- * XXX: come to think of it, because we want the sessions reused in
- * XXX: Most Recently Used order.
- * XXX: Another and maybe more interesting option would be to cache
- * XXX: free sessions in the worker threads and postpone session
- * XXX: allocation until then.  This does not quite implment MRU order
- * XXX: but it does save some locking, although not that much because
- * XXX: we still have to do the source-addr lookup.
  */
 
 #include "config.h"
@@ -56,6 +48,7 @@ struct sessmem {
 	unsigned		magic;
 #define SESSMEM_MAGIC		0x555859c5
 
+	struct sesspool		*pool;
 	struct sess		sess;
 	unsigned		workspace;
 	void			*wsp;
@@ -64,13 +57,16 @@ struct sessmem {
 	struct sockaddr_storage	sockaddr[2];
 };
 
-static VTAILQ_HEAD(,sessmem)	ses_free_mem[2] = {
-    VTAILQ_HEAD_INITIALIZER(ses_free_mem[0]),
-    VTAILQ_HEAD_INITIALIZER(ses_free_mem[1]),
+struct sesspool {
+	unsigned		magic;
+#define SESSPOOL_MAGIC		0xd916e202
+	VTAILQ_HEAD(,sessmem)	freelist;
+	struct lock		mtx;
+	unsigned		nsess;
+	unsigned		maxsess;
 };
 
-static unsigned ses_qp;
-static struct lock		ses_mem_mtx;
+static struct sesspool *sesspool;
 
 /*--------------------------------------------------------------------*/
 
@@ -106,8 +102,6 @@ ses_sm_alloc(void)
 	uint16_t nhttp;
 	unsigned l, hl;
 
-	if (VSC_C_main->n_sess_mem >= params->max_sess)
-		return (NULL);
 	/*
 	 * It is not necessary to lock these, but we need to
 	 * cache them locally, to make sure we get a consistent
@@ -115,6 +109,7 @@ ses_sm_alloc(void)
 	 */
 	nws = params->sess_workspace;
 	nhttp = (uint16_t)params->http_max_hdr;
+
 	hl = HTTP_estimate(nhttp);
 	l = sizeof *sm + nws + 2 * hl;
 	p = malloc(l);
@@ -122,6 +117,7 @@ ses_sm_alloc(void)
 		return (NULL);
 	q = p + l;
 
+	/* XXX Stats */
 	Lck_Lock(&stat_mtx);
 	VSC_C_main->n_sess_mem++;
 	Lck_Unlock(&stat_mtx);
@@ -153,7 +149,6 @@ ses_setup(struct sessmem *sm)
 {
 	struct sess *sp;
 
-
 	CHECK_OBJ_NOTNULL(sm, SESSMEM_MAGIC);
 	sp = &sm->sess;
 	memset(sp, 0, sizeof *sp);
@@ -184,39 +179,38 @@ ses_setup(struct sessmem *sm)
  */
 
 struct sess *
-SES_New(void)
+SES_New(struct sesspool *pp)
 {
 	struct sessmem *sm;
 	struct sess *sp;
+	int do_alloc = 0;
 
-	assert(pthread_self() == VCA_thread);
-	assert(ses_qp <= 1);
-	sm = VTAILQ_FIRST(&ses_free_mem[ses_qp]);
-	if (sm == NULL) {
-		/*
-		 * If that queue is empty, flip queues holding the lock
-		 * and try the new unlocked queue.
-		 */
-		Lck_Lock(&ses_mem_mtx);
-		ses_qp = 1 - ses_qp;
-		Lck_Unlock(&ses_mem_mtx);
-		sm = VTAILQ_FIRST(&ses_free_mem[ses_qp]);
-	}
+	if (pp == NULL)
+		pp = sesspool;
+	CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
+
+	Lck_Lock(&pp->mtx);
+	sm = VTAILQ_FIRST(&pp->freelist);
 	if (sm != NULL) {
-		VTAILQ_REMOVE(&ses_free_mem[ses_qp], sm, list);
-		sp = &sm->sess;
-		CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-	} else {
+		VTAILQ_REMOVE(&pp->freelist, sm, list);
+	} else if (pp->nsess < pp->maxsess) {
+		pp->nsess++;
+		do_alloc = 1;
+	}
+	Lck_Unlock(&pp->mtx);
+	if (do_alloc) {
 		sm = ses_sm_alloc();
-		if (sm == NULL)
-			return (NULL);
-		ses_setup(sm);
-		sp = &sm->sess;
-		CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+		if (sm != NULL) {
+			sm->pool = pp;
+			ses_setup(sm);
+		}
 	}
-
+	if (sm == NULL)
+		return (NULL);
+	sp = &sm->sess;
+	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+	/* XXX Stats */
 	VSC_C_main->n_sess++;		/* XXX: locking  ? */
-
 	return (sp);
 }
 
@@ -292,10 +286,14 @@ SES_Delete(struct sess *sp, const char *reason)
 	struct acct *b = &sp->acct_ses;
 	struct sessmem *sm;
 	static char noaddr[] = "-";
+	struct sesspool *pp;
+
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	sm = sp->mem;
 	CHECK_OBJ_NOTNULL(sm, SESSMEM_MAGIC);
+	pp = sm->pool;
+	CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
 
 	if (reason != NULL)
 		SES_Close(sp, reason);
@@ -314,28 +312,21 @@ SES_Delete(struct sess *sp, const char *reason)
 	    sp->addr, sp->port, sp->t_end - b->first,
 	    b->sess, b->req, b->pipe, b->pass,
 	    b->fetch, b->hdrbytes, b->bodybytes);
+
 	if (sm->workspace != params->sess_workspace) {
 		Lck_Lock(&stat_mtx);
 		VSC_C_main->n_sess_mem--;
 		Lck_Unlock(&stat_mtx);
 		free(sm);
+		Lck_Lock(&pp->mtx);
+		sesspool->nsess--;
+		Lck_Unlock(&pp->mtx);
 	} else {
 		/* Clean and prepare for reuse */
 		ses_setup(sm);
-		Lck_Lock(&ses_mem_mtx);
-		VTAILQ_INSERT_HEAD(&ses_free_mem[1 - ses_qp], sm, list);
-		Lck_Unlock(&ses_mem_mtx);
-	}
-
-	/* Try to precreate some ses-mem so the acceptor will not have to */
-	if (VSC_C_main->n_sess_mem < VSC_C_main->n_sess + 10) {
-		sm = ses_sm_alloc();
-		if (sm != NULL) {
-			ses_setup(sm);
-			Lck_Lock(&ses_mem_mtx);
-			VTAILQ_INSERT_HEAD(&ses_free_mem[1 - ses_qp], sm, list);
-			Lck_Unlock(&ses_mem_mtx);
-		}
+		Lck_Lock(&pp->mtx);
+		VTAILQ_INSERT_HEAD(&sesspool->freelist, sm, list);
+		Lck_Unlock(&pp->mtx);
 	}
 }
 
@@ -345,6 +336,10 @@ void
 SES_Init()
 {
 
+	ALLOC_OBJ(sesspool, SESSPOOL_MAGIC);
+	VTAILQ_INIT(&sesspool->freelist);
+	Lck_New(&sesspool->mtx, lck_sessmem);
+	sesspool->maxsess = params->max_sess;
+
 	Lck_New(&stat_mtx, lck_stat);
-	Lck_New(&ses_mem_mtx, lck_sessmem);
 }



More information about the varnish-commit mailing list