[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