[master] d13c674 Add stats counters for VSM usage/overflows.

Poul-Henning Kamp phk at varnish-cache.org
Thu Nov 24 11:02:16 CET 2011


commit d13c674d347663ec812c846f637b31ec48867ab5
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Nov 24 10:01:23 2011 +0000

    Add stats counters for VSM usage/overflows.
    
    Various minor polish to VSM area.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 190e945..5e813ca 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -850,7 +850,7 @@ int SES_Schedule(struct sess *sp);
 
 /* cache_shmlog.c */
 extern struct VSC_C_main *VSC_C_main;
-void VSL_Init(void);
+void VSM_Init(void);
 void *VSM_Alloc(unsigned size, const char *class, const char *type,
     const char *ident);
 void VSM_Free(void *ptr);
diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c
index 1f876cd..fd31de4 100644
--- a/bin/varnishd/cache/cache_main.c
+++ b/bin/varnishd/cache/cache_main.c
@@ -103,7 +103,7 @@ child_main(void)
 
 	THR_SetName("cache-main");
 
-	VSL_Init();	/* First, LCK needs it. */
+	VSM_Init();	/* First, LCK needs it. */
 
 	LCK_Init();	/* Second, locking */
 
diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c
index 01f6bce..893525b 100644
--- a/bin/varnishd/cache/cache_shmlog.c
+++ b/bin/varnishd/cache/cache_shmlog.c
@@ -38,6 +38,7 @@
 #include "cache_backend.h"	// For w->vbc
 
 #include "vmb.h"
+#include "vtim.h"
 
 /* These cannot be struct lock, which depends on vsm/vsl working */
 static pthread_mutex_t vsl_mtx;
@@ -299,10 +300,26 @@ WSLB(struct worker *w, enum VSL_tag_e tag, const char *fmt, ...)
 
 /*--------------------------------------------------------------------*/
 
+static void *
+vsm_cleaner(void *priv)
+{
+	(void)priv;
+	THR_SetName("vsm_cleaner");
+	while (1) {
+		AZ(pthread_mutex_lock(&vsm_mtx));
+		VSM_common_cleaner(heritage.vsm, VSC_C_main);
+		AZ(pthread_mutex_unlock(&vsm_mtx));
+		VTIM_sleep(1.1);
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
 void
-VSL_Init(void)
+VSM_Init(void)
 {
 	uint32_t *vsl_log_start;
+	pthread_t tp;
 
 	AZ(pthread_mutex_init(&vsl_mtx, NULL));
 	AZ(pthread_mutex_init(&vsm_mtx, NULL));
@@ -328,6 +345,8 @@ VSL_Init(void)
 	// VSM_head->starttime = (intmax_t)VTIM_real();
 	memset(VSC_C_main, 0, sizeof *VSC_C_main);
 	// VSM_head->child_pid = getpid();
+
+	AZ(pthread_create(&tp, NULL, vsm_cleaner, NULL));
 }
 
 /*--------------------------------------------------------------------*/
diff --git a/bin/varnishd/common/common.h b/bin/varnishd/common/common.h
index 0f25d31..2ff5623 100644
--- a/bin/varnishd/common/common.h
+++ b/bin/varnishd/common/common.h
@@ -69,12 +69,14 @@ void mgt_child_inherit(int fd, const char *what);
 
 /* vsm.c */
 struct vsm_sc;
+struct VSC_C_main;
 struct vsm_sc *VSM_common_new(void *ptr, ssize_t len);
 void *VSM_common_alloc(struct vsm_sc *sc, ssize_t size,
     const char *class, const char *type, const char *ident);
 void VSM_common_free(struct vsm_sc *sc, void *ptr);
 void VSM_common_delete(struct vsm_sc **sc);
 void VSM_common_copy(struct vsm_sc *to, const struct vsm_sc *from);
+void VSM_common_cleaner(struct vsm_sc *sc, struct VSC_C_main *stats);
 
 /*---------------------------------------------------------------------
  * Generic power-2 rounding macros
diff --git a/bin/varnishd/common/common_vsm.c b/bin/varnishd/common/common_vsm.c
index 3853ed8..e53972c 100644
--- a/bin/varnishd/common/common_vsm.c
+++ b/bin/varnishd/common/common_vsm.c
@@ -43,6 +43,7 @@
 #include "common.h"
 
 #include "vapi/vsm_int.h"
+#include "vapi/vsc_int.h"
 #include "vmb.h"
 #include "vtim.h"
 
@@ -69,6 +70,11 @@ struct vsm_sc {
 	VTAILQ_HEAD(,vsm_range)		r_cooling;
 	VTAILQ_HEAD(,vsm_range)		r_free;
 	VTAILQ_HEAD(,vsm_range)		r_bogus;
+	uint64_t			g_free;
+	uint64_t			g_used;
+	uint64_t			g_cooling;
+	uint64_t			g_overflow;
+	uint64_t			c_overflow;
 };
 
 /*--------------------------------------------------------------------
@@ -148,10 +154,37 @@ VSM_common_new(void *p, ssize_t l)
 	vr->off = RUP2(sizeof(*sc->head), 16);
 	vr->len = RDN2(l - vr->off, 16);
 	VTAILQ_INSERT_TAIL(&sc->r_free, vr, list);
+	sc->g_free = vr->len;
 	return (sc);
 }
 
 /*--------------------------------------------------------------------
+ * Move from cooling list to free list
+ */
+
+void
+VSM_common_cleaner(struct vsm_sc *sc, struct VSC_C_main *stats)
+{
+	double now = VTIM_real();
+	struct vsm_range *vr, *vr2;
+
+	CHECK_OBJ_NOTNULL(sc, VSM_SC_MAGIC);
+
+	/* Move cooled off stuff to free list */
+	VTAILQ_FOREACH_SAFE(vr, &sc->r_cooling, list, vr2) {
+		if (vr->cool > now)
+			break;
+		VTAILQ_REMOVE(&sc->r_cooling, vr, list);
+		vsm_common_insert_free(sc, vr);
+	}
+	stats->vsm_free = sc->g_free;
+	stats->vsm_used = sc->g_used;
+	stats->vsm_cooling = sc->g_cooling;
+	stats->vsm_overflow = sc->g_overflow;
+	stats->vsm_overflowed = sc->c_overflow;
+}
+
+/*--------------------------------------------------------------------
  * Allocate a chunk from VSM
  */
 
@@ -160,7 +193,6 @@ VSM_common_alloc(struct vsm_sc *sc, ssize_t size,
     const char *class, const char *type, const char *ident)
 {
 	struct vsm_range *vr, *vr2, *vr3;
-	double now = VTIM_real();
 	unsigned l1, l2;
 
 	CHECK_OBJ_NOTNULL(sc, VSM_SC_MAGIC);
@@ -174,14 +206,6 @@ VSM_common_alloc(struct vsm_sc *sc, ssize_t size,
 	AN(ident);
 	assert(strlen(ident) < sizeof(vr->chunk->ident));
 
-	/* Move cooled off stuff to free list */
-	VTAILQ_FOREACH_SAFE(vr, &sc->r_cooling, list, vr2) {
-		if (vr->cool > now)
-			break;
-		VTAILQ_REMOVE(&sc->r_cooling, vr, list);
-		vsm_common_insert_free(sc, vr);
-	}
-
 	l1 = RUP2(size + sizeof(struct VSM_chunk), 16);
 	l2 = RUP2(size + 2 * sizeof(struct VSM_chunk), 16);
 
@@ -213,12 +237,15 @@ VSM_common_alloc(struct vsm_sc *sc, ssize_t size,
 		AN(vr);
 		vr->ptr = malloc(size);
 		AN(vr->ptr);
+		vr->len = size;
 		VTAILQ_INSERT_TAIL(&sc->r_bogus, vr, list);
-		/* XXX: log + stats */
+		sc->g_overflow += vr->len;
+		sc->c_overflow += vr->len;
 		return (vr->ptr);
 	}
 
-	/* XXX: stats ? */
+	sc->g_free -= vr->len;
+	sc->g_used += vr->len;
 
 	/* Zero the entire allocation, to avoid garbage confusing readers */
 	memset(sc->b + vr->off, 0, vr->len);
@@ -263,7 +290,10 @@ VSM_common_free(struct vsm_sc *sc, void *ptr)
 	VTAILQ_FOREACH(vr, &sc->r_used, list) {
 		if (vr->ptr != ptr)
 			continue;
-		/* XXX: stats ? */
+
+		sc->g_used -= vr->len;
+		sc->g_cooling += vr->len;
+
 		vr2 = VTAILQ_NEXT(vr, list);
 		VTAILQ_REMOVE(&sc->r_used, vr, list);
 		VTAILQ_INSERT_TAIL(&sc->r_cooling, vr, list);
@@ -278,15 +308,18 @@ VSM_common_free(struct vsm_sc *sc, void *ptr)
 		VWMB();
 		return;
 	}
+
 	/* Look in bogus list, free */
 	VTAILQ_FOREACH(vr, &sc->r_bogus, list) {
-		if (vr->ptr == ptr) {
-			VTAILQ_REMOVE(&sc->r_bogus, vr, list);
-			FREE_OBJ(vr);
-			/* XXX: stats ? */
-			free(ptr);
-			return;
-		}
+		if (vr->ptr != ptr)
+			continue;
+
+		sc->g_overflow -= vr->len;
+
+		VTAILQ_REMOVE(&sc->r_bogus, vr, list);
+		FREE_OBJ(vr);
+		free(ptr);
+		return;
 	}
 	/* Panic */
 	assert(ptr == NULL);
@@ -326,7 +359,7 @@ VSM_common_delete(struct vsm_sc **scp)
 }
 
 /*--------------------------------------------------------------------
- * Copy one VSM to another
+ * Copy all chunks in one VSM segment to another VSM segment
  */
 
 void
diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h
index 72d8842..a04767d 100644
--- a/include/tbl/vsc_f_main.h
+++ b/include/tbl/vsc_f_main.h
@@ -359,3 +359,38 @@ VSC_F(vmods,		uint64_t, 0, 'i', "Loaded VMODs", "")
 
 VSC_F(n_gzip,			uint64_t, 0, 'a', "Gzip operations", "")
 VSC_F(n_gunzip,			uint64_t, 0, 'a', "Gunzip operations", "")
+
+/**********************************************************************/
+
+VSC_F(vsm_free,			uint64_t, 0, 'g',
+    "Free VSM space",
+	"Number of bytes free in the shared memory used to communicate"
+	" with tools like varnishstat, varnishlog etc."
+)
+
+VSC_F(vsm_used,			uint64_t, 0, 'g',
+    "Used VSM space",
+	"Number of bytes used in the shared memory used to communicate"
+	" with tools like varnishstat, varnishlog etc."
+)
+
+VSC_F(vsm_cooling,		uint64_t, 0, 'g',
+    "Cooling VSM space",
+	"Number of bytes which will soon (max 1 minute) be freed"
+	" in the shared memory used to communicate"
+	" with tools like varnishstat, varnishlog etc."
+)
+
+VSC_F(vsm_overflow,		uint64_t, 0, 'g',
+    "Overflow VSM space",
+	"Number of bytes which does not fit"
+	" in the shared memory used to communicate"
+	" with tools like varnishstat, varnishlog etc."
+)
+
+VSC_F(vsm_overflowed,		uint64_t, 0, 'c',
+    "Overflowed VSM space",
+	"Total number of bytes which did not fit"
+	" in the shared memory used to communicate"
+	" with tools like varnishstat, varnishlog etc."
+)
diff --git a/include/vapi/vsm_int.h b/include/vapi/vsm_int.h
index 237fabd..4272aef 100644
--- a/include/vapi/vsm_int.h
+++ b/include/vapi/vsm_int.h
@@ -37,7 +37,7 @@
  * In particular we want the readers to seamlessly jump from one VSM instance
  * to another when the child restarts.
  *
- * The VSM life-cycle there is:
+ * The VSM segment life-cycle is:
  *
  *	Manager creates VSM file under temp name
  *
@@ -54,7 +54,7 @@
  *	it will zero the alloc_seq in it, before replacing the file.
  *
  * Subscribers will have to monitor two things to make sure they have
- * the current VSM instance:  The alloc_seq field and the inode number
+ * the current VSM instance:  The alloc_seq field and the dev+inode
  * of the path-name.  The former check is by far the cheaper and the
  * latter check should only be employed when lack of activity in the
  * VSM segment raises suspicion that something has happened.



More information about the varnish-commit mailing list