Skip to content
This repository was archived by the owner on Jul 30, 2021. It is now read-only.

Commit 32af38d

Browse files
bsdphkLasse Karstensen
authored and
Lasse Karstensen
committed
Add a final backstop, so we absolutely 100% certainly do not
try to delete a objhead while it still has a waiting list, by forcing the last ref holder to rush the WL. Since the hasher owns the refcounts on objhead, we cannot just mingle req and objcore refcounts. Fortunately we don't need to add another refcounter, because all we really care about is the wl being empty when we drop the last ref. The wl/hsh_rush() mechanism will work differently with different thread-scheduling schenarios, and I cannot definitively rule out that we can drop the last ref on an oh, while there are still req's on the waiting list. Given that, and the existence proof in ticket #1823's race, this might have been the indicated memory-trampler. Conflicts: bin/varnishd/cache/cache_hash.c
1 parent c17c701 commit 32af38d

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

bin/varnishd/cache/cache_hash.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,10 +820,25 @@ HSH_DerefObjHead(struct worker *wrk, struct objhead **poh)
820820
oh->refcnt--;
821821
Lck_Unlock(&oh->mtx);
822822
return(1);
823-
} else if (oh->waitinglist != NULL) {
823+
}
824+
825+
/*
826+
* Make absolutely certain that we do not let the final ref
827+
* disappear until the waitinglist is empty.
828+
* This is necessary because the req's on the waiting list do
829+
* not hold any ref on the objhead of their own, and we cannot
830+
* just make the hold the same ref's as objcore, that would
831+
* confuse hashers.
832+
*/
833+
while (oh->waitinglist != NULL) {
824834
Lck_Lock(&oh->mtx);
835+
assert(oh->refcnt > 0);
836+
r = oh->refcnt;
825837
hsh_rush(wrk, oh);
826838
Lck_Unlock(&oh->mtx);
839+
if (r > 1)
840+
break;
841+
usleep(100000);
827842
}
828843

829844
assert(oh->refcnt > 0);

bin/varnishd/hash/hash_critbit.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,7 @@ hcb_start(void)
394394
static int __match_proto__(hash_deref_f)
395395
hcb_deref(struct objhead *oh)
396396
{
397-
int r;
398397

399-
r = 1;
400398
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
401399
Lck_Lock(&oh->mtx);
402400
assert(oh->refcnt > 0);
@@ -413,7 +411,7 @@ hcb_deref(struct objhead *oh)
413411
#ifdef PHK
414412
fprintf(stderr, "hcb_defef %d %d <%s>\n", __LINE__, r, oh->hash);
415413
#endif
416-
return (r);
414+
return (1);
417415
}
418416

419417
static struct objhead * __match_proto__(hash_lookup_f)

0 commit comments

Comments
 (0)