[PATCH 09/10] Force-expire segments on low storage in persistent

Martin Blix Grydeland martin at varnish-software.com
Wed Oct 10 16:27:22 CEST 2012


---
 bin/varnishd/storage/storage_persistent.c      |   47 +++++++++++++++++++++++-
 bin/varnishd/storage/storage_persistent.h      |    5 +++
 bin/varnishd/storage/storage_persistent_mgt.c  |    4 +-
 bin/varnishd/storage/storage_persistent_silo.c |   27 ++++++++++++++
 4 files changed, 79 insertions(+), 4 deletions(-)

diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c
index 00bd940..4306e4d 100644
--- a/bin/varnishd/storage/storage_persistent.c
+++ b/bin/varnishd/storage/storage_persistent.c
@@ -371,6 +371,10 @@ smp_save_segs(struct smp_sc *sc)
 		if (sg->flags & SMP_SEG_NEW)
 			break;
 		VTAILQ_REMOVE(&sc->segments, sg, list);
+		if (sg->flags & SMP_SEG_NUKED) {
+			assert(sc->free_pending >= sg->p.length);
+			sc->free_pending -= sg->p.length;
+		}
 		LRU_Free(sg->lru);
 		FREE_OBJ(sg);
 	}
@@ -406,6 +410,10 @@ smp_save_segs(struct smp_sc *sc)
 	VTAILQ_FOREACH(sg, &sc->segments, list) {
 		assert(sg->p.offset < sc->mediasize);
 		assert(sg->p.offset + sg->p.length <= sc->mediasize);
+		if (sg->flags & SMP_SEG_NUKED) {
+			AZ(length);
+			continue;
+		}
 		if (sg->flags & SMP_SEG_NEW)
 			break;
 		*ss = sg->p;
@@ -421,6 +429,39 @@ smp_save_segs(struct smp_sc *sc)
 	smp_sync_sign(&sc->seg2.ctx);
 	Lck_Lock(&sc->mtx);
 }
+
+/*
+ * Raise the free_reserve by nuking segments
+ */
+
+static void
+smp_raise_reserve(struct worker *wrk, struct vsl_log *vsl, struct smp_sc *sc)
+{
+	struct smp_seg *sg;
+
+	Lck_AssertHeld(&sc->mtx);
+
+	VTAILQ_FOREACH(sg, &sc->segments, list) {
+		if (sg == sc->cur_seg)
+			break;
+		if (smp_silospaceleft(sc) + sc->free_pending > sc->free_reserve)
+			break;
+		if (sg->flags & SMP_SEG_NEW)
+			break;
+		if (sg->flags & SMP_SEG_NUKED)
+			continue;
+
+		/* Nuke this segment */
+		Lck_Unlock(&sc->mtx);
+		EXP_NukeLRU(wrk, vsl, sg->lru);
+		Lck_Lock(&sc->mtx);
+		sg->flags |= SMP_SEG_NUKED;
+		sc->free_pending += sg->p.length;
+	}
+	assert(smp_silospaceleft(sc) + sc->free_pending > sc->free_reserve);
+	sc->flags &= ~SMP_SC_LOW;
+}
+
 /*--------------------------------------------------------------------
  * Silo worker thread
  */
@@ -430,10 +471,12 @@ smp_thread(struct worker *wrk, void *priv)
 {
 	struct smp_sc	*sc;
 	struct smp_seg *sg;
+	struct vsl_log vsl;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CAST_OBJ_NOTNULL(sc, priv, SMP_SC_MAGIC);
 	sc->thread = pthread_self();
+	VSL_Setup(&vsl, NULL, 0);
 
 	/* First, load all the objects from all segments */
 	VTAILQ_FOREACH(sg, &sc->segments, list)
@@ -448,10 +491,12 @@ smp_thread(struct worker *wrk, void *priv)
 	/* Housekeeping loop */
 	Lck_Lock(&sc->mtx);
 	while (!(sc->flags & SMP_SC_STOP)) {
+		if (sc->flags & SMP_SC_LOW)
+			smp_raise_reserve(wrk, &vsl, sc);
 		if (sc->flags & SMP_SC_SYNC)
 			smp_save_segs(sc);
 
-		if (!(sc->flags & (SMP_SC_SYNC | SMP_SC_STOP)))
+		if (!(sc->flags & (SMP_SC_LOW | SMP_SC_SYNC | SMP_SC_STOP)))
 			/* Wait for something to do */
 			(void)Lck_CondWait(&sc->cond, &sc->mtx, NULL);
 	}
diff --git a/bin/varnishd/storage/storage_persistent.h b/bin/varnishd/storage/storage_persistent.h
index 93ec45e..9e0642d 100644
--- a/bin/varnishd/storage/storage_persistent.h
+++ b/bin/varnishd/storage/storage_persistent.h
@@ -89,6 +89,7 @@ struct smp_seg {
 #define SMP_SEG_LOADED		(1 << 1)
 #define SMP_SEG_NEW		(1 << 2)
 #define SMP_SEG_SYNCSIGNS	(1 << 3)
+#define SMP_SEG_NUKED		(1 << 4)
 
 	uint32_t		nobj;		/* Number of objects */
 	uint32_t		nalloc;		/* Allocations */
@@ -114,6 +115,7 @@ struct smp_sc {
 #define SMP_SC_LOADED		(1 << 0)
 #define SMP_SC_STOP		(1 << 1)
 #define SMP_SC_SYNC		(1 << 2)
+#define SMP_SC_LOW		(1 << 3)
 
 	const struct stevedore	*stevedore;
 	int			fd;
@@ -133,6 +135,7 @@ struct smp_sc {
 	uint64_t		next_top;	/* next alloc address top */
 
 	uint64_t		free_offset;
+	uint64_t		free_pending;
 
 	pthread_t		thread;
 
@@ -224,6 +227,8 @@ void smp_msync(void *addr, size_t length);
 
 void smp_newsilo(struct smp_sc *sc);
 int smp_valid_silo(struct smp_sc *sc);
+uint64_t smp_silospaceleft(struct smp_sc *sc);
+void smp_check_reserve(struct smp_sc *sc);
 
 /*--------------------------------------------------------------------
  * Caculate payload of some stuff
diff --git a/bin/varnishd/storage/storage_persistent_mgt.c b/bin/varnishd/storage/storage_persistent_mgt.c
index c5b1dfd..26c9d36 100644
--- a/bin/varnishd/storage/storage_persistent_mgt.c
+++ b/bin/varnishd/storage/storage_persistent_mgt.c
@@ -114,9 +114,7 @@ smp_metrics(struct smp_sc *sc)
 	fprintf(stderr, "aim_nseg = %u, aim_segl = %ju\n",
 	    sc->aim_nseg, (uintmax_t)sc->aim_segl);
 
-	/*
-	 * How much space in the free reserve pool ?
-	 */
+	/* XXX: Random number larger than 1 */
 	sc->free_reserve = sc->aim_segl * 10;
 
 	fprintf(stderr, "free_reserve = %ju\n", (uintmax_t)sc->free_reserve);
diff --git a/bin/varnishd/storage/storage_persistent_silo.c b/bin/varnishd/storage/storage_persistent_silo.c
index addb836..e432302 100644
--- a/bin/varnishd/storage/storage_persistent_silo.c
+++ b/bin/varnishd/storage/storage_persistent_silo.c
@@ -184,6 +184,7 @@ smp_new_seg(struct smp_sc *sc)
 	sc->free_offset = sg->p.offset + sg->p.length;
 
 	VTAILQ_INSERT_TAIL(&sc->segments, sg, list);
+	smp_check_reserve(sc);
 
 	/* Set up our allocation points */
 	sc->cur_seg = sg;
@@ -270,6 +271,32 @@ smp_close_seg(struct smp_sc *sc, struct smp_seg *sg)
 	smp_sync_segs(sc);
 }
 
+uint64_t
+smp_silospaceleft(struct smp_sc *sc)
+{
+	struct smp_seg *sg;
+
+	Lck_AssertHeld(&sc->mtx);
+
+	sg = VTAILQ_FIRST(&sc->segments);
+	if (sg == NULL)
+		return (sc->mediasize - sc->free_offset);
+	if (sg->p.offset < sc->free_offset) {
+		return ((sc->mediasize - sc->free_offset) +
+			(sg->p.offset - sc->ident->stuff[SMP_SPC_STUFF]));
+	}
+	return (sg->p.offset - sc->free_offset);
+}
+
+void
+smp_check_reserve(struct smp_sc *sc)
+{
+	Lck_AssertHeld(&sc->mtx);
+
+	if (smp_silospaceleft(sc) + sc->free_pending < sc->free_reserve)
+		sc->flags |= SMP_SC_LOW;
+}
+
 /*---------------------------------------------------------------------
  */
 
-- 
1.7.9.5




More information about the varnish-dev mailing list