[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