[master] 12f5a29 Move HSH_Lookup() all the way to the V4 state, compensate backwards to V3 in cnt_lookup()

Poul-Henning Kamp phk at varnish-cache.org
Fri Apr 12 22:14:17 CEST 2013


commit 12f5a29c9721dc85467c18c4d290dac60406f06d
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Apr 12 20:13:02 2013 +0000

    Move HSH_Lookup() all the way to the V4 state, compensate backwards
    to V3 in cnt_lookup()
    
    Amazingly all the vtc's still pass.

diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index cfc4599..eab4907 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -304,31 +304,10 @@ hsh_insert_busyobj(struct worker *wrk, struct objhead *oh)
 }
 
 /*---------------------------------------------------------------------
- * XXX: future action:
- *
- *	if (always_miss)
- *		return (insert_busy_obj())
- *      switch (Lookup()) {
- *	case HIT:
- *		return (object);
- *	case BUSY_ONLY:
- *		if (!ignore_body)
- *			return (WAIT)
- *		// fallthrough
- *	case MISS:
- *		return (insert_busy_obj())
- *	case EXPIRED_AND_BUSY:
- *		if (!ignore_body)
- *			return (expired_object)
- *		// fallthrough
- *	case EXPIRED:
- *		return (expired_object + insert_busy_obj())
- *	}
- *
  */
 
 enum lookup_e
-HSH_Lookup(struct req *req, struct objcore **ocp, struct busyobj **bop,
+HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp,
     int wait_for_busy, int always_insert)
 {
 	struct worker *wrk;
@@ -338,11 +317,12 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct busyobj **bop,
 	struct object *o, *exp_o;
 	double exp_entered;
 	int busy_found;
+	enum lookup_e retval;
 
 	AN(ocp);
 	*ocp = NULL;
-	AN(bop);
-	*bop = NULL;
+	AN(bocp);
+	*bocp = NULL;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 	wrk = req->wrk;
@@ -374,7 +354,7 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct busyobj **bop,
 
 	if (always_insert) {
 		/* Insert new objcore in objecthead and release mutex */
-		*ocp = hsh_insert_busyobj(wrk, oh);
+		*bocp = hsh_insert_busyobj(wrk, oh);
 		/* NB: no deref of objhead, new object inherits reference */
 		Lck_Unlock(&oh->mtx);
 		return (HSH_MISS);
@@ -418,8 +398,17 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct busyobj **bop,
 
 		if (EXP_Ttl(req, o) >= req->t_req) {
 			/* If still valid, use it */
-			break;
-		} else if (o->exp.entered > exp_entered) {
+			assert(oh->refcnt > 1);
+			assert(oc->objhead == oh);
+			oc->refcnt++;
+			Lck_Unlock(&oh->mtx);
+			assert(HSH_DerefObjHead(&wrk->stats, &oh));
+			if (!cache_param->obj_readonly && o->hits < INT_MAX)
+				o->hits++;
+			*ocp = oc;
+			return (HSH_HIT);
+		}
+		if (o->exp.entered > exp_entered) {
 			/* record the newest object */
 			exp_oc = oc;
 			exp_o = o;
@@ -427,74 +416,66 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct busyobj **bop,
 		}
 	}
 
-	/*
-	 * If we have seen a busy object or the backend is unhealthy, and
-	 * we have an object in grace, use it, if req.grace is also
-	 * satisified.
-	 * XXX: VDI_Healty() call with oh->mtx is not so cool.
-	 */
+	if (exp_oc != NULL) {
+		AN(exp_o);
+		assert(oh->refcnt > 1);
+		assert(exp_oc->objhead == oh);
+		exp_oc->refcnt++;
 
-	AZ(req->objcore);
-	if (oc == NULL			/* We found no live object */
-	    && exp_oc != NULL		/* There is a grace candidate */
-	    && (busy_found		/* Somebody else is already busy */
-	    || !VDI_Healthy(req->director, req))) {
-					/* Or it is impossible to fetch */
-		oc = exp_oc;
-		o = exp_o;
+		if (!busy_found) {
+			AZ(req->hash_ignore_busy);
+			*bocp = hsh_insert_busyobj(wrk, oh);
+			retval = HSH_EXPBUSY;
+		} else {
+			retval = HSH_EXP;
+		}
+
+		Lck_Unlock(&oh->mtx);
+		if (retval == HSH_EXP)
+			assert(HSH_DerefObjHead(&wrk->stats, &oh));
+		if (!cache_param->obj_readonly && exp_o->hits < INT_MAX)
+			exp_o->hits++;
+		*ocp = exp_oc;
+		return (retval);
 	}
 
-	if (oc != NULL) {
-		AN(o);
-		/* We found an object we like */
-		assert(oh->refcnt > 1);
-		assert(oc->objhead == oh);
-		oc->refcnt++;
+	if (!busy_found) {
+		/* Insert objcore in objecthead and release mutex */
+		*bocp = hsh_insert_busyobj(wrk, oh);
+		/* NB: no deref of objhead, new object inherits reference */
 		Lck_Unlock(&oh->mtx);
-		assert(HSH_DerefObjHead(&wrk->stats, &oh));
-		if (!cache_param->obj_readonly && o->hits < INT_MAX)
-			o->hits++;
-		*ocp = oc;
-		return (HSH_HIT);
+		return (HSH_MISS);
 	}
 
-	if (busy_found) {
-		/* There are one or more busy objects, wait for them */
-		if (wait_for_busy) {
-			CHECK_OBJ_NOTNULL(wrk->nwaitinglist,
-			    WAITINGLIST_MAGIC);
-			if (oh->waitinglist == NULL) {
-				oh->waitinglist = wrk->nwaitinglist;
-				wrk->nwaitinglist = NULL;
-			}
-			VTAILQ_INSERT_TAIL(&oh->waitinglist->list,
-			    req, w_list);
-			if (DO_DEBUG(DBG_WAITINGLIST))
-				VSLb(req->vsl, SLT_Debug,
-					"on waiting list <%p>", oh);
-		} else {
-			if (DO_DEBUG(DBG_WAITINGLIST))
-				VSLb(req->vsl, SLT_Debug,
-					"hit busy obj <%p>", oh);
-		}
+	/* There are one or more busy objects, wait for them */
 
-		wrk->stats.busy_sleep++;
-		SES_Charge(req->wrk, req);
-		/*
-		 * The objhead reference transfers to the sess, we get it
-		 * back when the sess comes off the waiting list and
-		 * calls us again
-		 */
-		req->hash_objhead = oh;
-		Lck_Unlock(&oh->mtx);
-		return (HSH_BUSY);
+	AZ(req->hash_ignore_busy);
+
+	if (wait_for_busy) {
+		CHECK_OBJ_NOTNULL(wrk->nwaitinglist, WAITINGLIST_MAGIC);
+		if (oh->waitinglist == NULL) {
+			oh->waitinglist = wrk->nwaitinglist;
+			wrk->nwaitinglist = NULL;
+		}
+		VTAILQ_INSERT_TAIL(&oh->waitinglist->list,
+		    req, w_list);
+		if (DO_DEBUG(DBG_WAITINGLIST))
+			VSLb(req->vsl, SLT_Debug, "on waiting list <%p>", oh);
+	} else {
+		if (DO_DEBUG(DBG_WAITINGLIST))
+			VSLb(req->vsl, SLT_Debug, "hit busy obj <%p>", oh);
 	}
 
-	/* Insert (precreated) objcore in objecthead and release mutex */
-	*ocp = hsh_insert_busyobj(wrk, oh);
-	/* NB: no deref of objhead, new object inherits reference */
+	wrk->stats.busy_sleep++;
+	SES_Charge(req->wrk, req);
+	/*
+	 * The objhead reference transfers to the sess, we get it
+	 * back when the sess comes off the waiting list and
+	 * calls us again
+	 */
+	req->hash_objhead = oh;
 	Lck_Unlock(&oh->mtx);
-	return (HSH_MISS);
+	return (HSH_BUSY);
 }
 
 /*---------------------------------------------------------------------
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 6ce4f3f..5697481 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -736,7 +736,7 @@ DOT lookup:yes -> pass [style=bold,color=red]
 static enum req_fsm_nxt
 cnt_lookup(struct worker *wrk, struct req *req)
 {
-	struct objcore *oc;
+	struct objcore *oc, *boc;
 	struct object *o;
 	struct objhead *oh;
 	struct busyobj *bo;
@@ -752,7 +752,7 @@ cnt_lookup(struct worker *wrk, struct req *req)
 	VRY_Prep(req);
 
 	AZ(req->objcore);
-	lr = HSH_Lookup(req, &oc, &bo,
+	lr = HSH_Lookup(req, &oc, &boc,
 	    req->esi_level == 0 ? 1 : 0,
 	    req->hash_always_miss ? 1 : 0
 	);
@@ -767,6 +767,45 @@ cnt_lookup(struct worker *wrk, struct req *req)
 	}
 	AZ(req->objcore);
 
+
+	switch (lr) {
+	case HSH_EXP:
+VSLb(req->vsl, SLT_Debug, "XXXX EXP\n");
+		AN(oc);
+		AZ(boc);
+		break;
+	case HSH_EXPBUSY:
+VSLb(req->vsl, SLT_Debug, "XXXX EXPBUSY\n");
+		AN(oc);
+		AN(boc);
+		if (VDI_Healthy(req->director, req)) {
+VSLb(req->vsl, SLT_Debug, "deref oc\n");
+			(void)HSH_Deref(&wrk->stats, oc, NULL);
+			oc = boc;
+			boc = NULL;
+		} else {
+VSLb(req->vsl, SLT_Debug, "drop boc\n");
+			(void)HSH_Deref(&wrk->stats, boc, NULL);
+			boc = NULL;
+		}
+		break;
+	case HSH_MISS:
+VSLb(req->vsl, SLT_Debug, "XXXX MISS\n");
+		AZ(oc);
+		AN(boc);
+		oc = boc;
+		boc = NULL;
+		AN(oc->flags & OC_F_BUSY);
+		break;
+	case HSH_HIT:
+VSLb(req->vsl, SLT_Debug, "XXXX HIT\n");
+		AN(oc);
+		AZ(boc);
+		break;
+	default:
+		INCOMPL();
+	}
+
 	CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
 	oh = oc->objhead;
 	CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
diff --git a/bin/varnishd/default.vcl b/bin/varnishd/default.vcl
index cfd5880..f6c7833 100644
--- a/bin/varnishd/default.vcl
+++ b/bin/varnishd/default.vcl
@@ -94,9 +94,20 @@ sub vcl_hash {
 }
 
 sub vcl_lookup {
+/*
+    if (!obj) {
+	    return (deliver);
+    }
     if (obj.uncacheable) {
 	return (pass);
     }
+    if (obj.ttl >= 0s) {
+	return (deliver);
+    }
+    if (obj.ttl + obj.grace > 0s) {
+	return (deliver_stale);
+    }
+*/
     return (deliver);
 }
 
@@ -104,6 +115,7 @@ sub vcl_miss {
     return (fetch);
 }
 
+
 sub vcl_fetch {
     return (fetch);
 }
diff --git a/bin/varnishd/hash/hash_slinger.h b/bin/varnishd/hash/hash_slinger.h
index 76a47a7..ec6a4f2 100644
--- a/bin/varnishd/hash/hash_slinger.h
+++ b/bin/varnishd/hash/hash_slinger.h
@@ -63,7 +63,7 @@ enum lookup_e {
 
 /* cache_hash.c */
 void HSH_Cleanup(struct worker *w);
-enum lookup_e HSH_Lookup(struct req *, struct objcore **, struct busyobj **,
+enum lookup_e HSH_Lookup(struct req *, struct objcore **, struct objcore **,
     int wait_for_busy, int always_insert);
 // struct objcore *HSH_Lookup(struct req *, int wait_for_busy, int always_insert);
 void HSH_Ref(struct objcore *o);



More information about the varnish-commit mailing list