Commit 4db1c75a authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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: http://www.varnish-cache.org/svn/trunk/varnish-cache@3841 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 3b38e393
...@@ -652,7 +652,9 @@ DOT lookup -> miss [label="no",style=bold,color=blue,weight=2] ...@@ -652,7 +652,9 @@ DOT lookup -> miss [label="no",style=bold,color=blue,weight=2]
static int static int
cnt_lookup(struct sess *sp) cnt_lookup(struct sess *sp)
{ {
struct objcore *oc;
struct object *o; struct object *o;
struct objhead *oh;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
...@@ -663,9 +665,9 @@ cnt_lookup(struct sess *sp) ...@@ -663,9 +665,9 @@ cnt_lookup(struct sess *sp)
assert(sp->handling == VCL_RET_HASH); 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 * We lost the session to a busy object, disembark the
* worker thread. The hash code to restart the session, * worker thread. The hash code to restart the session,
...@@ -674,16 +676,31 @@ cnt_lookup(struct sess *sp) ...@@ -674,16 +676,31 @@ cnt_lookup(struct sess *sp)
return (1); return (1);
} }
sp->obj = o; CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
/* If we inserted a new object it's a miss */ /* If we inserted a new object it's a miss */
if (ObjIsBusy(sp->obj)) { if (oc->flags & OC_F_BUSY) {
VSL_stats->cache_miss++; 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; sp->step = STP_MISS;
return (0); 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++; VSL_stats->cache_hitpass++;
WSP(sp, SLT_HitPass, "%u", sp->obj->xid); WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
HSH_Deref(sp->wrk, &sp->obj); HSH_Deref(sp->wrk, &sp->obj);
......
...@@ -264,13 +264,14 @@ HSH_AddString(struct sess *sp, const char *str) ...@@ -264,13 +264,14 @@ HSH_AddString(struct sess *sp, const char *str)
sp->lhashptr += l + 1; sp->lhashptr += l + 1;
} }
struct object * struct objcore *
HSH_Lookup(struct sess *sp) HSH_Lookup(struct sess *sp, struct objhead **poh)
{ {
struct worker *w; struct worker *w;
struct objhead *oh; struct objhead *oh;
struct objcore *oc; 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, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
...@@ -296,17 +297,19 @@ HSH_Lookup(struct sess *sp) ...@@ -296,17 +297,19 @@ HSH_Lookup(struct sess *sp)
Lck_Lock(&oh->mtx); Lck_Lock(&oh->mtx);
} }
busy_o = NULL; busy_oc = NULL;
grace_o = NULL; grace_oc = NULL;
o = NULL;
VTAILQ_FOREACH(oc, &oh->objcs, list) { 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; o = oc->obj;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
if (ObjIsBusy(o)) {
busy_o = o;
continue;
}
if (!o->cacheable) if (!o->cacheable)
continue; continue;
if (o->ttl == 0) if (o->ttl == 0)
...@@ -322,33 +325,39 @@ HSH_Lookup(struct sess *sp) ...@@ -322,33 +325,39 @@ HSH_Lookup(struct sess *sp)
/* Remember any matching objects inside their grace period */ /* Remember any matching objects inside their grace period */
if (o->ttl + HSH_Grace(o->grace) >= sp->t_req) 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, * If we have seen a busy object, and have an object in grace,
* use it, if req.grace is also satisified. * 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 && if (oc == NULL && grace_oc != NULL && busy_oc != NULL) {
busy_o != NULL && o = grace_oc->obj;
grace_o->ttl + HSH_Grace(sp->grace) >= sp->t_req) CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
o = grace_o; 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 */ /* We found an object we like */
o->refcnt++; o->refcnt++;
if (o->hits < INT_MAX) if (o->hits < INT_MAX)
o->hits++; o->hits++;
Lck_Unlock(&oh->mtx); Lck_Unlock(&oh->mtx);
assert(hash->deref(oh)); 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 */ /* There are one or more busy objects, wait for them */
if (sp->esis == 0) if (sp->esis == 0)
VTAILQ_INSERT_TAIL(&oh->waitinglist, sp, list); VTAILQ_INSERT_TAIL(&oh->waitinglist, sp, list);
...@@ -361,26 +370,17 @@ HSH_Lookup(struct sess *sp) ...@@ -361,26 +370,17 @@ HSH_Lookup(struct sess *sp)
return (NULL); return (NULL);
} }
/* Insert (precreated) object in objecthead */ /* Insert (precreated) objcore in objecthead */
o = w->nobj;
w->nobj = NULL;
oc = w->nobjcore; oc = w->nobjcore;
w->nobjcore = NULL; 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 ? */ /* XXX: Should this not be ..._HEAD now ? */
VTAILQ_INSERT_TAIL(&oh->objcs, oc, list); VTAILQ_INSERT_TAIL(&oh->objcs, oc, list);
/* NB: do not deref objhead the new object inherits our reference */ /* NB: do not deref objhead the new object inherits our reference */
Lck_Unlock(&oh->mtx); Lck_Unlock(&oh->mtx);
/* *poh = oh;
* XXX: This may be too early, relative to pass objects. return (oc);
* XXX: possibly move to when we commit to have it in the cache.
*/
BAN_NewObj(o);
return (o);
} }
static void static void
...@@ -432,6 +432,7 @@ HSH_Unbusy(const struct sess *sp) ...@@ -432,6 +432,7 @@ HSH_Unbusy(const struct sess *sp)
o = sp->obj; o = sp->obj;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
AN(ObjIsBusy(o)); AN(ObjIsBusy(o));
assert(o->objcore->obj == o);
assert(o->refcnt > 0); assert(o->refcnt > 0);
if (o->ws_o->overflow) if (o->ws_o->overflow)
VSL_stats->n_objoverflow++; VSL_stats->n_objoverflow++;
......
...@@ -54,7 +54,7 @@ void HSH_Prealloc(struct sess *sp); ...@@ -54,7 +54,7 @@ void HSH_Prealloc(struct sess *sp);
void HSH_Cleanup(struct worker *w); void HSH_Cleanup(struct worker *w);
void HSH_Freestore(struct object *o); void HSH_Freestore(struct object *o);
void HSH_Copy(const struct sess *sp, struct objhead *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_Unbusy(const struct sess *sp);
void HSH_Ref(struct object *o); void HSH_Ref(struct object *o);
void HSH_Drop(struct sess *sp); void HSH_Drop(struct sess *sp);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment