r3841 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Sat Feb 28 19:18:23 CET 2009


Author: phk
Date: 2009-02-28 19:18:23 +0100 (Sat, 28 Feb 2009)
New Revision: 3841

Modified:
   trunk/varnish-cache/bin/varnishd/cache_center.c
   trunk/varnish-cache/bin/varnishd/cache_hash.c
   trunk/varnish-cache/bin/varnishd/hash_slinger.h
Log:
On a cache-miss, insert only the (busy) objcore, leave the actual
object allocation and insertion for later in cache_center.c

For now, do it right away in cache_center, before going to STP_MISS.



Modified: trunk/varnish-cache/bin/varnishd/cache_center.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_center.c	2009-02-28 17:20:19 UTC (rev 3840)
+++ trunk/varnish-cache/bin/varnishd/cache_center.c	2009-02-28 18:18:23 UTC (rev 3841)
@@ -652,7 +652,9 @@
 static int
 cnt_lookup(struct sess *sp)
 {
+	struct objcore *oc;
 	struct object *o;
+	struct objhead *oh;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
@@ -663,9 +665,9 @@
 		assert(sp->handling == VCL_RET_HASH);
 	}
 
-	o = HSH_Lookup(sp);
+	oc = HSH_Lookup(sp, &oh);
 
-	if (o == NULL) {
+	if (oc == NULL) {
 		/*
 		 * We lost the session to a busy object, disembark the
 		 * worker thread.   The hash code to restart the session,
@@ -674,16 +676,31 @@
 		return (1);
 	}
 
-	sp->obj = o;
+	CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
 
 	/* If we inserted a new object it's a miss */
-	if (ObjIsBusy(sp->obj)) {
+	if (oc->flags & OC_F_BUSY) {
 		VSL_stats->cache_miss++;
+
+		AZ(oc->obj);
+		o = sp->wrk->nobj;
+		sp->wrk->nobj = NULL;
+
+		o->objhead = oh;
+		o->objcore = oc;
+		oc->obj = o;
+		sp->obj = o;
+
+		BAN_NewObj(o);
 		sp->step = STP_MISS;
 		return (0);
 	}
 
-	if (sp->obj->objcore->flags & OC_F_PASS) {
+	o = oc->obj;
+	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+	sp->obj = o;
+
+	if (oc->flags & OC_F_PASS) {
 		VSL_stats->cache_hitpass++;
 		WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
 		HSH_Deref(sp->wrk, &sp->obj);

Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_hash.c	2009-02-28 17:20:19 UTC (rev 3840)
+++ trunk/varnish-cache/bin/varnishd/cache_hash.c	2009-02-28 18:18:23 UTC (rev 3841)
@@ -264,13 +264,14 @@
 	sp->lhashptr += l + 1;
 }
 
-struct object *
-HSH_Lookup(struct sess *sp)
+struct objcore *
+HSH_Lookup(struct sess *sp, struct objhead **poh)
 {
 	struct worker *w;
 	struct objhead *oh;
 	struct objcore *oc;
-	struct object *o, *busy_o, *grace_o;
+	struct objcore *busy_oc, *grace_oc;
+	struct object *o;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
@@ -296,17 +297,19 @@
 		Lck_Lock(&oh->mtx);
 	}
 
-	busy_o = NULL;
-	grace_o = NULL;
-	o = NULL;
+	busy_oc = NULL;
+	grace_oc = NULL;
 	VTAILQ_FOREACH(oc, &oh->objcs, list) {
+		CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
+
+		if (oc->flags & OC_F_BUSY) {
+			busy_oc = oc;
+			continue;
+		}
+
 		o = oc->obj;
 		CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
 		
-		if (ObjIsBusy(o)) {
-			busy_o = o;
-			continue;
-		}
 		if (!o->cacheable)
 			continue;
 		if (o->ttl == 0)
@@ -322,33 +325,39 @@
 
 		/* Remember any matching objects inside their grace period */
 		if (o->ttl + HSH_Grace(o->grace) >= sp->t_req)
-			grace_o = o;
+			grace_oc = oc;
 	}
-	if (oc == NULL)
-		o = NULL;
-	else
-		AN(o);
 
 	/*
 	 * If we have seen a busy object, and have an object in grace,
 	 * use it, if req.grace is also satisified.
+	 * XXX: Interesting footnote:  The busy object might be for a
+	 * XXX: different "Vary:" than we sought.  We have no way of knowing
+	 * XXX: this until the object is unbusy'ed, so in practice we
+	 * XXX: serialize fetch of all Vary's if grace is possible.
 	 */
-	if (o == NULL && grace_o != NULL &&
-	    busy_o != NULL &&
-	    grace_o->ttl + HSH_Grace(sp->grace) >= sp->t_req)
-		o = grace_o;
+	if (oc == NULL && grace_oc != NULL && busy_oc != NULL) {
+		o = grace_oc->obj;
+		CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+		if (o->ttl + HSH_Grace(sp->grace) >= sp->t_req)
+			oc = grace_oc;
+	}
 
-	if (o != NULL) {
+	if (oc != NULL) {
+		o = oc->obj;
+		CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
+
 		/* We found an object we like */
 		o->refcnt++;
 		if (o->hits < INT_MAX)
 			o->hits++;
 		Lck_Unlock(&oh->mtx);
 		assert(hash->deref(oh));
-		return (o);
+		*poh = oh;
+		return (oc);
 	}
 
-	if (busy_o != NULL) {
+	if (busy_oc != NULL) {
 		/* There are one or more busy objects, wait for them */
 		if (sp->esis == 0)
 			VTAILQ_INSERT_TAIL(&oh->waitinglist, sp, list);
@@ -361,26 +370,17 @@
 		return (NULL);
 	}
 
-	/* Insert (precreated) object in objecthead */
-	o = w->nobj;
-	w->nobj = NULL;
-
+	/* Insert (precreated) objcore in objecthead */
 	oc = w->nobjcore;
 	w->nobjcore = NULL;
+	AN(oc->flags & OC_F_BUSY);
 
-	o->objhead = oh;
-	o->objcore = oc;
-	oc->obj = o;
 	/* XXX: Should this not be ..._HEAD now ? */
 	VTAILQ_INSERT_TAIL(&oh->objcs, oc, list);
 	/* NB: do not deref objhead the new object inherits our reference */
 	Lck_Unlock(&oh->mtx);
-	/*
-	 * XXX: This may be too early, relative to pass objects.
-	 * XXX: possibly move to when we commit to have it in the cache.
-	 */
-	BAN_NewObj(o);
-	return (o);
+	*poh = oh;
+	return (oc);
 }
 
 static void
@@ -432,6 +432,7 @@
 	o = sp->obj;
 	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
 	AN(ObjIsBusy(o));
+	assert(o->objcore->obj == o);
 	assert(o->refcnt > 0);
 	if (o->ws_o->overflow)
 		VSL_stats->n_objoverflow++;

Modified: trunk/varnish-cache/bin/varnishd/hash_slinger.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/hash_slinger.h	2009-02-28 17:20:19 UTC (rev 3840)
+++ trunk/varnish-cache/bin/varnishd/hash_slinger.h	2009-02-28 18:18:23 UTC (rev 3841)
@@ -54,7 +54,7 @@
 void HSH_Cleanup(struct worker *w);
 void HSH_Freestore(struct object *o);
 void HSH_Copy(const struct sess *sp, struct objhead *o);
-struct object *HSH_Lookup(struct sess *sp);
+struct objcore *HSH_Lookup(struct sess *sp, struct objhead **poh);
 void HSH_Unbusy(const struct sess *sp);
 void HSH_Ref(struct object *o);
 void HSH_Drop(struct sess *sp);



More information about the varnish-commit mailing list