[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