[master] 0dd1ee2 Complete the busyobj management code by adding a (default-on) per worker cache and a wrapper structure (needed for $param sized elements) and two new stats counters.

Poul-Henning Kamp phk at varnish-cache.org
Thu Dec 8 08:13:45 CET 2011


commit 0dd1ee21b69f043ad55219c592454d17dd8739db
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Dec 8 07:12:33 2011 +0000

    Complete the busyobj management code by adding a (default-on) per
    worker cache and a wrapper structure (needed for $param sized elements)
    and two new stats counters.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 0ee855b..4435c32 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -106,6 +106,7 @@ struct pool;
 struct sess;
 struct sesspool;
 struct vbc;
+struct vbo;
 struct vef_priv;
 struct vrt_backend;
 struct vsb;
@@ -293,7 +294,7 @@ struct worker {
 	struct objhead		*nobjhead;
 	struct objcore		*nobjcore;
 	struct waitinglist	*nwaitinglist;
-	/* struct busyobj		*nbusyobj; */
+	struct vbo		*nvbo;
 	void			*nhashpriv;
 	struct dstat		stats;
 
@@ -496,9 +497,7 @@ oc_getlru(const struct objcore *oc)
 struct busyobj {
 	unsigned		magic;
 #define BUSYOBJ_MAGIC		0x23b95567
-	struct lock		mtx;
-	/* Members passed this line are cleared on reuse */
-	unsigned		refcount;
+	struct vbo		*vbo;
 
 	uint8_t			*vary;
 	unsigned		is_gzip;
@@ -700,8 +699,9 @@ double BAN_Time(const struct ban *ban);
 /* cache_busyobj.c */
 void VBO_Init(void);
 struct busyobj *VBO_GetBusyObj(struct worker *wrk);
-struct busyobj *VBO_RefBusyObj(struct busyobj *busyobj);
+void VBO_RefBusyObj(const struct busyobj *busyobj);
 void VBO_DerefBusyObj(struct worker *wrk, struct busyobj **busyobj);
+void VBO_Free(struct vbo **vbo);
 
 /* cache_center.c [CNT] */
 void CNT_Session(struct sess *sp);
diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c
index 32bad7e..4272725 100644
--- a/bin/varnishd/cache/cache_busyobj.c
+++ b/bin/varnishd/cache/cache_busyobj.c
@@ -1,8 +1,8 @@
 /*-
- * Copyright (c) 2006 Verdens Gang AS
- * Copyright (c) 2006-2011 Varnish Software AS
+ * Copyright (c) 2011 Varnish Software AS
  * All rights reserved.
  *
+ * Author: Martin Blix Grydeland <martin at varnish-software.com>
  * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,101 +38,141 @@
 
 #include "cache.h"
 
-static struct lock nbusyobj_mtx;
-static struct busyobj *nbusyobj;
+struct vbo {
+	unsigned		magic;
+#define VBO_MAGIC		0xde3d8223
+	struct lock		mtx;
+	unsigned		refcount;
+	struct busyobj		bo;
+};
+
+static struct lock vbo_mtx;
+static struct vbo *nvbo;
 
 void
 VBO_Init(void)
 {
-	Lck_New(&nbusyobj_mtx, lck_nbusyobj);
-	nbusyobj = NULL;
+	Lck_New(&vbo_mtx, lck_busyobj);
+	nvbo = NULL;
 }
 
 /*--------------------------------------------------------------------
  * BusyObj handling
  */
 
-static struct busyobj *
-vbo_NewBusyObj(void)
+static struct vbo *
+vbo_New(void)
 {
-	struct busyobj *busyobj;
+	struct vbo *vbo;
 
-	ALLOC_OBJ(busyobj, BUSYOBJ_MAGIC);
-	AN(busyobj);
-	Lck_New(&busyobj->mtx, lck_busyobj);
-	return (busyobj);
+	ALLOC_OBJ(vbo, VBO_MAGIC);
+	AN(vbo);
+	Lck_New(&vbo->mtx, lck_busyobj);
+	return (vbo);
 }
 
-static void
-vbe_FreeBusyObj(struct busyobj *busyobj)
+void
+VBO_Free(struct vbo **vbop)
 {
-	CHECK_OBJ_NOTNULL(busyobj, BUSYOBJ_MAGIC);
-	AZ(busyobj->refcount);
-	Lck_Delete(&busyobj->mtx);
-	FREE_OBJ(busyobj);
+	struct vbo *vbo;
+
+	AN(vbop);
+	vbo = *vbop;
+	*vbop = NULL;
+	CHECK_OBJ_NOTNULL(vbo, VBO_MAGIC);
+	AZ(vbo->refcount);
+	Lck_Delete(&vbo->mtx);
+	FREE_OBJ(vbo);
 }
 
 struct busyobj *
 VBO_GetBusyObj(struct worker *wrk)
 {
-	struct busyobj *busyobj = NULL;
-
-	(void)wrk;
-	Lck_Lock(&nbusyobj_mtx);
-	if (nbusyobj != NULL) {
-		CHECK_OBJ_NOTNULL(nbusyobj, BUSYOBJ_MAGIC);
-		busyobj = nbusyobj;
-		nbusyobj = NULL;
-		memset((char *)busyobj + offsetof(struct busyobj, refcount), 0,
-		       sizeof *busyobj - offsetof(struct busyobj, refcount));
+	struct vbo *vbo = NULL;
+
+	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+
+	if (wrk->nvbo != NULL) {
+		vbo = wrk->nvbo;
+		wrk->nvbo = NULL;
+	}
+
+	if (vbo == NULL) {
+		Lck_Lock(&vbo_mtx);
+
+		vbo = nvbo;
+		nvbo = NULL;
+
+		if (vbo == NULL)
+			VSC_C_main->busyobj_alloc++;
+
+		Lck_Unlock(&vbo_mtx);
 	}
-	Lck_Unlock(&nbusyobj_mtx);
-	if (busyobj == NULL)
-		busyobj = vbo_NewBusyObj();
-	AN(busyobj);
-	busyobj->refcount = 1;
-	busyobj->beresp = wrk->x_beresp;
-	busyobj->bereq = wrk->x_bereq;
-	return (busyobj);
+
+	if (vbo == NULL)
+		vbo = vbo_New();
+
+	CHECK_OBJ_NOTNULL(vbo, VBO_MAGIC);
+	AZ(vbo->refcount);
+	AZ(vbo->bo.magic);
+	vbo->refcount = 1;
+	vbo->bo.magic = BUSYOBJ_MAGIC;
+	vbo->bo.vbo = vbo;
+	vbo->bo.beresp = wrk->x_beresp;
+	vbo->bo.bereq = wrk->x_bereq;
+	return (&vbo->bo);
 }
 
-struct busyobj *
-VBO_RefBusyObj(struct busyobj *busyobj)
+void
+VBO_RefBusyObj(const struct busyobj *busyobj)
 {
+	struct vbo *vbo;
+
 	CHECK_OBJ_NOTNULL(busyobj, BUSYOBJ_MAGIC);
-	Lck_Lock(&busyobj->mtx);
-	assert(busyobj->refcount > 0);
-	busyobj->refcount++;
-	Lck_Unlock(&busyobj->mtx);
-	return (busyobj);
+	vbo = busyobj->vbo;
+	CHECK_OBJ_NOTNULL(vbo, VBO_MAGIC);
+	Lck_Lock(&vbo->mtx);
+	assert(vbo->refcount > 0);
+	vbo->refcount++;
+	Lck_Unlock(&vbo->mtx);
 }
 
 void
 VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo)
 {
-	struct busyobj *busyobj;
+	struct busyobj *bo;
+	struct vbo *vbo;
+	unsigned r;
 
-	(void)wrk;
-	busyobj = *pbo;
-	CHECK_OBJ_NOTNULL(busyobj, BUSYOBJ_MAGIC);
-	Lck_Lock(&busyobj->mtx);
-	assert(busyobj->refcount > 0);
-	busyobj->refcount--;
+	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+	AN(pbo);
+	bo = *pbo;
 	*pbo = NULL;
-	if (busyobj->refcount > 0) {
-		Lck_Unlock(&busyobj->mtx);
-		return;
-	}
-	Lck_Unlock(&busyobj->mtx);
-
-	/* XXX Sanity checks e.g. AZ(busyobj->vbc) */
-
-	Lck_Lock(&nbusyobj_mtx);
-	if (nbusyobj == NULL) {
-		nbusyobj = busyobj;
-		busyobj = NULL;
+	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	vbo = bo->vbo;
+	CHECK_OBJ_NOTNULL(vbo, VBO_MAGIC);
+	Lck_Lock(&vbo->mtx);
+	assert(vbo->refcount > 0);
+	r = --vbo->refcount;
+	Lck_Unlock(&vbo->mtx);
+
+	if (r == 0) {
+		/* XXX: Sanity checks & cleanup */
+		memset(&vbo->bo, 0, sizeof vbo->bo);
+
+		if (cache_param->bo_cache && wrk->nvbo == NULL) {
+			wrk->nvbo = vbo;
+		} else {
+			Lck_Lock(&vbo_mtx);
+			if (nvbo == NULL) {
+				nvbo = vbo;
+				vbo = NULL;
+			} else
+				VSC_C_main->busyobj_free++;
+			Lck_Unlock(&vbo_mtx);
+
+			if (vbo != NULL)
+				VBO_Free(&vbo);
+		}
 	}
-	Lck_Unlock(&nbusyobj_mtx);
-	if (busyobj != NULL)
-		vbe_FreeBusyObj(busyobj);
 }
diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index 675afea..6f6a85f 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -134,10 +134,8 @@ HSH_Cleanup(struct worker *wrk)
 		free(wrk->nhashpriv);
 		wrk->nhashpriv = NULL;
 	}
-	/* if (wrk->nbusyobj != NULL) { */
-	/* 	FREE_OBJ(wrk->nbusyobj); */
-	/* 	wrk->nbusyobj = NULL; */
-	/* } */
+	if (wrk->nvbo != NULL)
+		VBO_Free(&wrk->nvbo);
 }
 
 void
diff --git a/bin/varnishd/common/params.h b/bin/varnishd/common/params.h
index b9b758f..8fd777f 100644
--- a/bin/varnishd/common/params.h
+++ b/bin/varnishd/common/params.h
@@ -189,6 +189,8 @@ struct params {
 
 	struct vre_limits	vre_limits;
 
+	unsigned		bo_cache;
+
 	/* VSM dimensions */
 	ssize_t			vsm_space;
 	ssize_t			vsl_space;
diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c
index e4be5d8..cc14e41 100644
--- a/bin/varnishd/mgt/mgt_param.c
+++ b/bin/varnishd/mgt/mgt_param.c
@@ -1105,6 +1105,14 @@ static const struct parspec input_parspec[] = {
 		MUST_RESTART,
 		"1M", "bytes"},
 
+	{ "busyobj_worker_cache", tweak_bool,
+		&mgt_param.bo_cache, 0, 0,
+		"Cache free busyobj per worker thread."
+		"Disable this if you have very high hitrates and want"
+		"to save the memory of one busyobj per worker thread.",
+		0,
+		"true", ""},
+
 	{ NULL, NULL, NULL }
 };
 
diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h
index a04767d..ab8415c 100644
--- a/include/tbl/vsc_f_main.h
+++ b/include/tbl/vsc_f_main.h
@@ -235,6 +235,20 @@ VSC_F(sess_dropped,		uint64_t, 1, 'c',
 	"  See also param queue_max."
 )
 
+/*---------------------------------------------------------------------
+ * BusyObj
+ */
+
+VSC_F(busyobj_alloc,		uint64_t, 1, 'c',
+    "Busyobj allocations",
+	"Number of busyobj structures allocated."
+)
+
+VSC_F(busyobj_free,		uint64_t, 1, 'c',
+    "Busyobj freed",
+	"Number of busyobj structures freed."
+)
+
 /*---------------------------------------------------------------------*/
 
 VSC_F(n_sess_mem,		uint64_t, 0, 'i', "N struct sess_mem", "")



More information about the varnish-commit mailing list