Skip to content
This repository was archived by the owner on Feb 16, 2026. It is now read-only.

Commit 856488c

Browse files
committed
hash: New HSH_WalkAway() function
When there's no rush, a request can simply walk away from the queue. The concept is simple: when a factor (pun intended) other than the backend fetch requires the request to leave the queue, it can just walk away. It short-circuits the usual rush exit. We can repurpose the dead counter busy_killed to count those events, and get rid of the dead enum entry HSH_CONTINUE.
1 parent b75b21b commit 856488c

6 files changed

Lines changed: 62 additions & 2 deletions

File tree

bin/varnishd/cache/cache_hash.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,12 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp)
464464
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
465465
Lck_AssertHeld(&oh->mtx);
466466

467+
if (req->walkaway) {
468+
assert(oh->refcnt > 0);
469+
(void)hsh_deref_objhead_unlock(wrk, &oh, 0);
470+
return (HSH_WALKAWAY);
471+
}
472+
467473
if (req->hash_always_miss) {
468474
/* XXX: should we do predictive Vary in this case ? */
469475
/* Insert new objcore in objecthead and release mutex */
@@ -699,6 +705,42 @@ hsh_rush2(struct worker *wrk, struct rush *r)
699705
}
700706
}
701707

708+
void
709+
HSH_WalkAway(struct worker *wrk, struct objhead **ohp, struct req *req)
710+
{
711+
struct objhead *oh;
712+
struct rush r[1];
713+
714+
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
715+
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
716+
TAKE_OBJ_NOTNULL(oh, ohp, OBJHEAD_MAGIC);
717+
718+
INIT_OBJ(r, RUSH_MAGIC);
719+
VTAILQ_INIT(&r->reqs);
720+
721+
if (DO_DEBUG(DBG_WAITINGLIST))
722+
VSLb(req->vsl, SLT_Debug, "walking away <%p>", oh);
723+
724+
Lck_Lock(&oh->mtx);
725+
if (req->waitinglist) {
726+
assert(oh == req->hash_objhead);
727+
assert(oh->refcnt > 1);
728+
oh->refcnt--;
729+
VTAILQ_REMOVE(&oh->waitinglist, req, w_list);
730+
VTAILQ_INSERT_TAIL(&r->reqs, req, w_list);
731+
Lck_Unlock(&oh->mtx);
732+
733+
wrk->stats->busy_killed++;
734+
AZ(req->walkaway);
735+
req->walkaway = 1;
736+
hsh_rush2(wrk, r);
737+
} else {
738+
AZ(req->hash_objhead);
739+
assert(oh->refcnt > 0);
740+
(void)hsh_deref_objhead_unlock(wrk, &oh, 0);
741+
}
742+
}
743+
702744
/*---------------------------------------------------------------------
703745
* Purge an entire objhead
704746
*/

bin/varnishd/cache/cache_objhead.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,4 @@ unsigned HSH_Purge(struct worker *, struct objhead *, vtim_real ttl_now,
7676
vtim_dur ttl, vtim_dur grace, vtim_dur keep);
7777
struct objcore *HSH_Private(const struct worker *wrk);
7878
void HSH_Cancel(struct worker *, struct objcore *, struct boc *);
79+
void HSH_WalkAway(struct worker *wrk, struct objhead **ohp, struct req *req);

bin/varnishd/cache/cache_req_fsm.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,21 @@ cnt_lookup(struct worker *wrk, struct req *req)
561561
had_objhead = 1;
562562
wrk->strangelove = 0;
563563
lr = HSH_Lookup(req, &oc, &busy);
564+
if (lr == HSH_WALKAWAY) {
565+
VRY_Finish(req, DISCARD);
566+
AZ(req->objcore);
567+
AZ(req->stale_oc);
568+
VSLb_ts_req(req, "Waitinglist", W_TIM_real(wrk));
569+
VSLb(req->vsl, SLT_Error, "The client is going away");
570+
if (req->esi_level > 0) {
571+
/* NB: Interrupt delivery upwards to avoid engaging
572+
* new sub-request tasks.
573+
*/
574+
req->req_step = R_STP_VCLFAIL;
575+
return (REQ_FSM_MORE);
576+
}
577+
return (REQ_FSM_DONE);
578+
}
564579
if (lr == HSH_BUSY) {
565580
/*
566581
* We lost the session to a busy object, disembark the

bin/varnishd/hash/hash_slinger.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ struct hash_slinger {
5252
};
5353

5454
enum lookup_e {
55-
HSH_CONTINUE,
55+
HSH_WALKAWAY,
5656
HSH_MISS,
5757
HSH_BUSY,
5858
HSH_HIT,

include/tbl/req_flags.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ REQ_FLAG(is_hitpass, 1, 0, "")
4242
REQ_FLAG(waitinglist, 0, 0, "")
4343
REQ_FLAG(want100cont, 0, 0, "")
4444
REQ_FLAG(late100cont, 0, 0, "")
45+
REQ_FLAG(walkaway, 0, 0, "")
4546
#undef REQ_FLAG
4647

4748
/*lint -restore */

lib/libvsc/VSC_main.vsc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,11 @@
319319
Number of requests taken off the busy object sleep list and rescheduled.
320320

321321
.. varnish_vsc:: busy_killed
322+
:group: wrk
322323
:oneliner: Number of requests killed after sleep on busy objhdr
323324

324325
Number of requests killed from the busy object sleep list due to
325-
lack of resources.
326+
the client going away.
326327

327328
.. varnish_vsc:: sess_queued
328329
:oneliner: Sessions queued for thread

0 commit comments

Comments
 (0)