From ce66d331604996d1b112d8a76be6e2f7c8bff29d Mon Sep 17 00:00:00 2001 From: phk Date: Sat, 28 Feb 2009 18:18:23 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@3841 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache_center.c | 27 +++++++-- varnish-cache/bin/varnishd/cache_hash.c | 71 ++++++++++++----------- varnish-cache/bin/varnishd/hash_slinger.h | 2 +- 3 files changed, 59 insertions(+), 41 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index 2e23fc8a..216099b2 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -652,7 +652,9 @@ DOT lookup -> miss [label="no",style=bold,color=blue,weight=2] 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 @@ cnt_lookup(struct sess *sp) 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 @@ cnt_lookup(struct sess *sp) 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); diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c index b35f2d8e..599f8e73 100644 --- a/varnish-cache/bin/varnishd/cache_hash.c +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -264,13 +264,14 @@ HSH_AddString(struct sess *sp, const char *str) 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 @@ HSH_Lookup(struct sess *sp) 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 @@ HSH_Lookup(struct sess *sp) /* 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 (oc != NULL) { + o = oc->obj; + CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); - if (o != NULL) { /* 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 @@ HSH_Lookup(struct sess *sp) 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 @@ HSH_Unbusy(const struct sess *sp) 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++; diff --git a/varnish-cache/bin/varnishd/hash_slinger.h b/varnish-cache/bin/varnishd/hash_slinger.h index e37297fc..1e764613 100644 --- a/varnish-cache/bin/varnishd/hash_slinger.h +++ b/varnish-cache/bin/varnishd/hash_slinger.h @@ -54,7 +54,7 @@ void HSH_Prealloc(struct sess *sp); 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); -- 2.39.5