[3.0] 596246e Make n_sess be the difference between in use and released session objects.

Martin Blix Grydeland martin at varnish-cache.org
Thu Jul 12 09:46:24 CEST 2012


commit 596246ea3fc36847dc27d1672dd37a8fef817ac5
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Thu Jun 28 14:43:12 2012 +0200

    Make n_sess be the difference between in use and released session
    objects.
    
    This avoids a memory race on the n_sess counter, which can lead to
    excessive session object allocation. Keeping the counters of in use
    and released separate allows the acceptor to continue to run lockless.
    
    Fixes: #897

diff --git a/bin/varnishd/cache_session.c b/bin/varnishd/cache_session.c
index 1ebca44..d94ac7b 100644
--- a/bin/varnishd/cache_session.c
+++ b/bin/varnishd/cache_session.c
@@ -74,6 +74,8 @@ static struct lock		ses_mem_mtx;
 /*--------------------------------------------------------------------*/
 
 static struct lock		stat_mtx;
+static volatile uint64_t	n_sess_grab = 0;
+static uint64_t			n_sess_rel = 0;
 
 /*--------------------------------------------------------------------*/
 
@@ -214,7 +216,8 @@ SES_New(void)
 		CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	}
 
-	VSC_C_main->n_sess++;		/* XXX: locking  ? */
+	/* Only updated from the cache acceptor - no lock needed */
+	n_sess_grab++;
 
 	return (sp);
 }
@@ -255,7 +258,6 @@ SES_Delete(struct sess *sp)
 
 	AZ(sp->obj);
 	AZ(sp->vcl);
-	VSC_C_main->n_sess--;			/* XXX: locking ? */
 	assert(!isnan(b->first));
 	assert(!isnan(sp->t_end));
 	if (sp->addr == NULL)
@@ -267,10 +269,8 @@ SES_Delete(struct sess *sp)
 	    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);
+		sm = NULL;
 	} else {
 		/* Clean and prepare for reuse */
 		ses_setup(sm);
@@ -279,6 +279,14 @@ SES_Delete(struct sess *sp)
 		Lck_Unlock(&ses_mem_mtx);
 	}
 
+	/* Update statistics */
+	Lck_Lock(&stat_mtx);
+	if (sm == NULL)
+		VSC_C_main->n_sess_mem--;
+	n_sess_rel++;
+	VSC_C_main->n_sess = n_sess_grab - n_sess_rel;
+	Lck_Unlock(&stat_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();



More information about the varnish-commit mailing list