[master] ee303d875 hash: Make HSH_Fail() rush the waiting list
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Wed Aug 27 15:23:05 UTC 2025
commit ee303d875257f9896369c889a3fddc2c8917f68a
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Mon Jan 22 15:55:55 2024 +0100
hash: Make HSH_Fail() rush the waiting list
This is not a nice caching outcome. In fact, when a fetch fails we don't
know the outcome. In that case we need to rush one request that will
trigger a new fetch and hopefully complete with a proper outcome to rush
other requests accordingly.
As far as lookup is concerned there is no point in keeping the OC_F_BUSY
flag so in the case where a failure happens before a proper HSH_Unbusy()
it can be dropped before the rush. This would otherwise happen once the
last objcore reference is dropped. One is held by the current fetch task
and the other one by the client task that triggerred the fetch. It would
amount to an unnecessary delay.
The OC_F_FAILED flag will prevent it from being looked up, so there is
no reason to delay the rush until the final objcore reference is dropped.
This also means that once the client task that triggered the fetch task
resumes it can only be operating on a non-busy object.
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index c707a22b6..79798847d 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -1060,9 +1060,8 @@ vbf_stp_fail(struct worker *wrk, struct busyobj *bo)
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
assert(oc->boc->state < BOS_FINISHED);
- HSH_Fail(oc);
- if (!(oc->flags & OC_F_BUSY))
- HSH_Kill(oc);
+ HSH_Fail(wrk, oc);
+ HSH_Kill(oc);
ObjSetState(wrk, oc, BOS_FAILED);
return (F_STP_DONE);
}
@@ -1250,11 +1249,9 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
(void)VRB_Ignore(req);
} else {
ObjWaitState(oc, BOS_STREAM);
- if (oc->boc->state == BOS_FAILED) {
- AN((oc->flags & OC_F_FAILED));
- } else {
- AZ(oc->flags & OC_F_BUSY);
- }
+ AZ(oc->flags & OC_F_BUSY);
+ if (oc->boc->state == BOS_FAILED)
+ AN(oc->flags & OC_F_FAILED);
}
}
AZ(bo);
diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index cd7c85c74..ed8244f2a 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -816,14 +816,17 @@ HSH_Purge(struct worker *wrk, struct objhead *oh, vtim_real ttl_now,
*/
void
-HSH_Fail(struct objcore *oc)
+HSH_Fail(struct worker *wrk, struct objcore *oc)
{
struct objhead *oh;
+ struct rush rush;
+ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
CHECK_OBJ_NOTNULL(oc->boc, BOC_MAGIC);
oh = oc->objhead;
CHECK_OBJ(oh, OBJHEAD_MAGIC);
+ INIT_OBJ(&rush, RUSH_MAGIC);
/*
* We either failed before the end of vcl_backend_response
@@ -842,7 +845,12 @@ HSH_Fail(struct objcore *oc)
Lck_Lock(&oh->mtx);
oc->flags |= OC_F_FAILED;
+ if (oc->flags & OC_F_BUSY) {
+ oc->flags &= ~OC_F_BUSY;
+ hsh_rush1(wrk, oh, &rush, 1);
+ }
Lck_Unlock(&oh->mtx);
+ hsh_rush2(wrk, &rush);
}
/*---------------------------------------------------------------------
diff --git a/bin/varnishd/cache/cache_objhead.h b/bin/varnishd/cache/cache_objhead.h
index 2edfb5a88..866dbc4a2 100644
--- a/bin/varnishd/cache/cache_objhead.h
+++ b/bin/varnishd/cache/cache_objhead.h
@@ -65,11 +65,11 @@ enum lookup_e {
HSH_BUSY,
};
-void HSH_Fail(struct objcore *);
void HSH_Kill(struct objcore *);
void HSH_Replace(struct objcore *, const struct objcore *);
void HSH_Insert(struct worker *, const void *hash, struct objcore *,
struct ban *);
+void HSH_Fail(struct worker *, struct objcore *);
void HSH_Unbusy(struct worker *, struct objcore *);
int HSH_Snipe(const struct worker *, struct objcore *);
struct boc *HSH_RefBoc(const struct objcore *);
More information about the varnish-commit
mailing list