
martin at varnish-software
Jan 22, 2012, 9:53 AM
Post #1 of 1
(36 views)
Permalink
|
|
[PATCH 03/25] BusyObj handling improvements
|
|
Fix double allocations of busyobj in some cases Make VBO_DerefBusyObj return refcount after decrementation Make VBO_RefBusyObj return a pointer to the ref'ed busyobj Make objcore's have a refcount on the busyobj Drop const from VBO_RefBusyObj arg BusyObj lock-less mode --- bin/varnishd/cache/cache.h | 5 +++-- bin/varnishd/cache/cache_busyobj.c | 22 +++++++++++++++------- bin/varnishd/cache/cache_center.c | 36 +++++++++++++++++++----------------- bin/varnishd/cache/cache_hash.c | 10 ++++++++-- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 7fcd41e..4f260e9 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -501,6 +501,7 @@ struct busyobj { unsigned magic; #define BUSYOBJ_MAGIC 0x23b95567 struct vbo *vbo; + unsigned use_locks; uint8_t *vary; unsigned is_gzip; @@ -733,8 +734,8 @@ double BAN_Time(const struct ban *ban); /* cache_busyobj.c */ void VBO_Init(void); struct busyobj *VBO_GetBusyObj(struct worker *wrk); -void VBO_RefBusyObj(const struct busyobj *busyobj); -void VBO_DerefBusyObj(struct worker *wrk, struct busyobj **busyobj); +struct busyobj *VBO_RefBusyObj(struct busyobj *busyobj); +unsigned VBO_DerefBusyObj(struct worker *wrk, struct busyobj **busyobj); void VBO_Free(struct vbo **vbo); /* cache_center.c [CNT] */ diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index ab4db76..b8b6fd7 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -144,21 +144,25 @@ VBO_GetBusyObj(struct worker *wrk) return (&vbo->bo); } -void -VBO_RefBusyObj(const struct busyobj *busyobj) +struct busyobj * +VBO_RefBusyObj(struct busyobj *busyobj) { struct vbo *vbo; CHECK_OBJ_NOTNULL(busyobj, BUSYOBJ_MAGIC); vbo = busyobj->vbo; CHECK_OBJ_NOTNULL(vbo, VBO_MAGIC); - Lck_Lock(&vbo->mtx); + if (busyobj->use_locks) + Lck_Lock(&vbo->mtx); assert(vbo->refcount > 0); vbo->refcount++; - Lck_Unlock(&vbo->mtx); + if (busyobj->use_locks) + Lck_Unlock(&vbo->mtx); + + return (busyobj); } -void +unsigned VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo) { struct busyobj *bo; @@ -172,10 +176,12 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo) CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); vbo = bo->vbo; CHECK_OBJ_NOTNULL(vbo, VBO_MAGIC); - Lck_Lock(&vbo->mtx); + if (bo->use_locks) + Lck_Lock(&vbo->mtx); assert(vbo->refcount > 0); r = --vbo->refcount; - Lck_Unlock(&vbo->mtx); + if (bo->use_locks) + Lck_Unlock(&vbo->mtx); if (r == 0) { /* XXX: Sanity checks & cleanup */ @@ -196,4 +202,6 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo) VBO_Free(&vbo); } } + + return (r); } diff --git a/bin/varnishd/cache/cache_center.c b/bin/varnishd/cache/cache_center.c index f9908b3..2909212 100644 --- a/bin/varnishd/cache/cache_center.c +++ b/bin/varnishd/cache/cache_center.c @@ -119,6 +119,7 @@ cnt_wait(struct sess *sp, struct worker *wrk, struct req *req) AZ(req->esi_level); assert(req->xid == 0); req->t_resp = NAN; + AZ(wrk->busyobj); assert(!isnan(sp->t_req)); tmo = (int)(1e3 * cache_param->timeout_linger); @@ -381,12 +382,11 @@ cnt_done(struct sess *sp, struct worker *wrk, struct req *req) CHECK_OBJ_ORNULL(req->vcl, VCL_CONF_MAGIC); AZ(req->obj); + AZ(req->objcore); AZ(wrk->busyobj); req->director = NULL; req->restarts = 0; - wrk->busyobj = NULL; - SES_Charge(sp); /* If we did an ESI include, don't mess up our state */ @@ -535,7 +535,7 @@ cnt_error(struct sess *sp, struct worker *wrk, struct req *req) if (req->handling == VCL_RET_RESTART && req->restarts < cache_param->max_restarts) { HSH_Drop(wrk); - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); req->director = NULL; req->restarts++; sp->step = STP_RECV; @@ -552,7 +552,7 @@ cnt_error(struct sess *sp, struct worker *wrk, struct req *req) req->err_code = 0; req->err_reason = NULL; http_Setup(wrk->busyobj->bereq, NULL); - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); sp->step = STP_PREPRESP; return (0); } @@ -680,7 +680,7 @@ cnt_fetch(struct sess *sp, struct worker *wrk, struct req *req) AZ(HSH_Deref(wrk, req->objcore, NULL)); req->objcore = NULL; } - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); req->director = NULL; req->storage_hint = NULL; @@ -852,7 +852,7 @@ cnt_fetchbody(struct sess *sp, struct worker *wrk, struct req *req) req->err_code = 503; sp->step = STP_ERROR; VDI_CloseFd(wrk, &wrk->busyobj->vbc); - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); return (0); } CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); @@ -922,7 +922,7 @@ cnt_fetchbody(struct sess *sp, struct worker *wrk, struct req *req) if (i) { HSH_Drop(wrk); - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); AZ(req->obj); req->err_code = 503; sp->step = STP_ERROR; @@ -935,7 +935,7 @@ cnt_fetchbody(struct sess *sp, struct worker *wrk, struct req *req) AN(req->obj->objcore->ban); HSH_Unbusy(wrk); } - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); wrk->acct_tmp.fetch++; sp->step = STP_PREPRESP; return (0); @@ -1011,7 +1011,7 @@ cnt_streambody(struct sess *sp, struct worker *wrk, struct req *req) assert(WRW_IsReleased(wrk)); assert(wrk->wrw.ciov == wrk->wrw.siov); (void)HSH_Deref(wrk, NULL, &req->obj); - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); http_Setup(req->resp, NULL); sp->step = STP_DONE; return (0); @@ -1103,6 +1103,10 @@ cnt_hit(struct sess *sp, struct worker *wrk, struct req *req) /* Drop our object, we won't need it */ (void)HSH_Deref(wrk, NULL, &req->obj); req->objcore = NULL; + if (wrk->busyobj != NULL) { + CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); + } switch(req->handling) { case VCL_RET_PASS: @@ -1274,7 +1278,6 @@ cnt_miss(struct sess *sp, struct worker *wrk, struct req *req) AN(req->objcore); CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC); WS_Reset(wrk->ws, NULL); - wrk->busyobj = VBO_GetBusyObj(wrk); http_Setup(wrk->busyobj->bereq, wrk->ws); http_FilterReq(sp, HTTPH_R_FETCH); http_ForceGet(wrk->busyobj->bereq); @@ -1299,13 +1302,13 @@ cnt_miss(struct sess *sp, struct worker *wrk, struct req *req) AZ(HSH_Deref(wrk, req->objcore, NULL)); req->objcore = NULL; http_Setup(wrk->busyobj->bereq, NULL); - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); sp->step = STP_ERROR; return (0); case VCL_RET_PASS: AZ(HSH_Deref(wrk, req->objcore, NULL)); req->objcore = NULL; - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); sp->step = STP_PASS; return (0); case VCL_RET_FETCH: @@ -1315,7 +1318,7 @@ cnt_miss(struct sess *sp, struct worker *wrk, struct req *req) case VCL_RET_RESTART: AZ(HSH_Deref(wrk, req->objcore, NULL)); req->objcore = NULL; - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); INCOMPL(); default: WRONG("Illegal action in vcl_miss{}"); @@ -1364,7 +1367,6 @@ cnt_pass(struct sess *sp, struct worker *wrk, struct req *req) AZ(req->obj); AZ(wrk->busyobj); - wrk->busyobj = VBO_GetBusyObj(wrk); WS_Reset(wrk->ws, NULL); wrk->busyobj = VBO_GetBusyObj(wrk); http_Setup(wrk->busyobj->bereq, wrk->ws); @@ -1376,7 +1378,7 @@ cnt_pass(struct sess *sp, struct worker *wrk, struct req *req) VCL_pass_method(sp); if (req->handling == VCL_RET_ERROR) { http_Setup(wrk->busyobj->bereq, NULL); - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); sp->step = STP_ERROR; return (0); } @@ -1423,7 +1425,6 @@ cnt_pipe(struct sess *sp, struct worker *wrk, const struct req *req) AZ(wrk->busyobj); wrk->acct_tmp.pipe++; - wrk->busyobj = VBO_GetBusyObj(wrk); WS_Reset(wrk->ws, NULL); wrk->busyobj = VBO_GetBusyObj(wrk); http_Setup(wrk->busyobj->bereq, wrk->ws); @@ -1438,7 +1439,7 @@ cnt_pipe(struct sess *sp, struct worker *wrk, const struct req *req) PipeSession(sp); assert(WRW_IsReleased(wrk)); http_Setup(wrk->busyobj->bereq, NULL); - VBO_DerefBusyObj(wrk, &wrk->busyobj); + (void)VBO_DerefBusyObj(wrk, &wrk->busyobj); sp->step = STP_DONE; return (0); } @@ -1577,6 +1578,7 @@ cnt_start(struct sess *sp, struct worker *wrk, struct req *req) AZ(req->vcl); EXP_Clr(&req->exp); AZ(req->esi_level); + AZ(wrk->busyobj); /* Update stats of various sorts */ wrk->stats.client_req++; diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index d967291..e78eb60 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -306,6 +306,7 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) AN(sp->req->director); AN(hash); wrk = sp->wrk; + AZ(wrk->busyobj); HSH_Prealloc(sp); memcpy(sp->wrk->nobjhead->digest, sp->req->digest, @@ -459,7 +460,7 @@ HSH_Lookup(struct sess *sp, struct objhead **poh) wrk->busyobj->vary = sp->req->vary_b; else wrk->busyobj->vary = NULL; - oc->busyobj = wrk->busyobj; + oc->busyobj = VBO_RefBusyObj(wrk->busyobj); /* * Busy objects go on the tail, so they will not trip up searches. @@ -622,7 +623,8 @@ HSH_Unbusy(struct worker *wrk) VTAILQ_REMOVE(&oh->objcs, oc, list); VTAILQ_INSERT_HEAD(&oh->objcs, oc, list); oc->flags &= ~OC_F_BUSY; - oc->busyobj = NULL; + if (oc->busyobj != NULL) + (void)VBO_DerefBusyObj(wrk, &oc->busyobj); if (oh->waitinglist != NULL) hsh_rush(oh); AN(oc->ban); @@ -710,6 +712,10 @@ HSH_Deref(struct worker *wrk, struct objcore *oc, struct object **oo) BAN_DestroyObj(oc); AZ(oc->ban); + if (oc->busyobj != NULL) + (void)VBO_DerefBusyObj(wrk, &oc->busyobj); + AZ(oc->busyobj); + if (oc->methods != NULL) { oc_freeobj(oc); wrk->stats.n_object--; -- 1.7.4.1 _______________________________________________ varnish-dev mailing list varnish-dev [at] varnish-cache https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
|