varnish-cache/bin/varnishd/cache/cache_hash.c
0
/*-
1
 * Copyright (c) 2006 Verdens Gang AS
2
 * Copyright (c) 2006-2015 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * SPDX-License-Identifier: BSD-2-Clause
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 *
30
 * This is the central hash-table code, it relies on a chosen hash
31
 * implementation only for the actual hashing, all the housekeeping
32
 * happens here.
33
 *
34
 * We have two kinds of structures, objecthead and object.  An objecthead
35
 * corresponds to a given (Host:, URL) tuple, and the objects hung from
36
 * the objecthead may represent various variations (ie: Vary: header,
37
 * different TTL etc) instances of that web-entity.
38
 *
39
 * Each objecthead has a mutex which locks both its own fields, the
40
 * list of objects and fields in the objects.
41
 *
42
 * The hash implementation must supply a reference count facility on
43
 * the objecthead, and return with a reference held after a lookup.
44
 *
45
 * Lookups in the hash implementation returns with a ref held and each
46
 * object hung from the objhead holds a ref as well.
47
 *
48
 * Objects have refcounts which are locked by the objecthead mutex.
49
 *
50
 * New objects are always marked busy, and they can go from busy to
51
 * not busy only once.
52
 */
53
54
#include "config.h"
55
56
#include <stdio.h>
57
#include <stdlib.h>
58
59
#include "cache_varnishd.h"
60
61
#include "cache/cache_objhead.h"
62
#include "cache/cache_transport.h"
63
64
#include "hash/hash_slinger.h"
65
66
#include "vsha256.h"
67
68
struct rush {
69
        unsigned                magic;
70
#define RUSH_MAGIC              0xa1af5f01
71
        VTAILQ_HEAD(,req)       reqs;
72
};
73
74
static const struct hash_slinger *hash;
75
#define PRIVATE_OH_EXP 7
76
static struct objhead private_ohs[1 << PRIVATE_OH_EXP];
77
78
static void hsh_rush1(const struct worker *, struct objcore *,
79
    struct rush *);
80
static void hsh_rush2(struct worker *, struct rush *);
81
static int hsh_deref_objhead(struct worker *wrk, struct objhead **poh);
82
static int hsh_deref_objhead_unlock(struct worker *wrk, struct objhead **poh,
83
    struct objcore *oc);
84
static int hsh_deref_objcore_unlock(struct worker *, struct objcore **);
85
86
/*---------------------------------------------------------------------*/
87
88
#define VCF_RETURN(x) const struct vcf_return VCF_##x[1] = { \
89
        { .name = #x, } \
90
};
91
92
VCF_RETURNS()
93
#undef VCF_RETURN
94
95
/*---------------------------------------------------------------------*/
96
97
static void
98 4918617
hsh_initobjhead(struct objhead *oh)
99
{
100
101 4918617
        XXXAN(oh);
102 4918617
        INIT_OBJ(oh, OBJHEAD_MAGIC);
103 4918617
        oh->refcnt = 1;
104 4918617
        oh->waitinglist_gen = 1;
105 4918617
        VTAILQ_INIT(&oh->objcs);
106 4918617
        VTAILQ_INIT(&oh->waitinglist);
107 4918617
        Lck_New(&oh->mtx, lck_objhdr);
108 4918617
}
109
110
static struct objhead *
111 63319
hsh_newobjhead(void)
112
{
113 63319
        struct objhead *oh = malloc(sizeof *oh);
114 63319
        hsh_initobjhead(oh);
115 63319
        return (oh);
116
}
117
118
/*---------------------------------------------------------------------*/
119
/* Precreate an objhead and object for later use */
120
static void
121 107240
hsh_prealloc(struct worker *wrk)
122
{
123
124 107240
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
125
126 107240
        if (wrk->wpriv->nobjcore == NULL)
127 72418
                wrk->wpriv->nobjcore = ObjNew(wrk);
128 107240
        CHECK_OBJ_NOTNULL(wrk->wpriv->nobjcore, OBJCORE_MAGIC);
129
130 107240
        if (wrk->wpriv->nobjhead == NULL) {
131 63321
                wrk->wpriv->nobjhead = hsh_newobjhead();
132 63321
                wrk->stats->n_objecthead++;
133 63321
        }
134 107240
        CHECK_OBJ_NOTNULL(wrk->wpriv->nobjhead, OBJHEAD_MAGIC);
135
136 107240
        if (hash->prep != NULL)
137 107000
                hash->prep(wrk);
138 107240
}
139
140
/*---------------------------------------------------------------------*/
141
142
// https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimization-that-the-world-forgot-or-a-better-alternative-to-integer-modulo/
143
static inline size_t
144 56720
fib(uint64_t n, uint8_t bits)
145
{
146 56720
        const uint64_t gr = 11400714819323198485LLU;
147
        uint64_t r;
148
149 56720
        r = n * gr;
150 56720
        r >>= (sizeof(gr) * 8) - bits;
151 56720
        assert(r < (size_t)1 << bits);
152 56720
        return ((size_t)r);
153
}
154
155
struct objcore *
156 56720
HSH_Private(const struct worker *wrk)
157
{
158
        struct objcore *oc;
159
        struct objhead *oh;
160
161 56720
        oh = &private_ohs[fib((uintptr_t)wrk, PRIVATE_OH_EXP)];
162 56720
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
163
164 56720
        oc = ObjNew(wrk);
165 56720
        AN(oc);
166 56720
        oc->refcnt = 1;
167 56720
        oc->objhead = oh;
168 56720
        oc->flags |= OC_F_PRIVATE;
169 56720
        Lck_Lock(&oh->mtx);
170 56720
        VTAILQ_INSERT_TAIL(&oh->objcs, oc, hsh_list);
171 56720
        oh->refcnt++;
172 56720
        Lck_Unlock(&oh->mtx);
173 56720
        return (oc);
174
}
175
176
/*---------------------------------------------------------------------*/
177
178
void
179 38353
HSH_Cleanup(const struct worker *wrk)
180
{
181
182 38353
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
183 38353
        CHECK_OBJ_NOTNULL(wrk->wpriv, WORKER_PRIV_MAGIC);
184 38353
        if (wrk->wpriv->nobjcore != NULL)
185 72
                ObjDestroy(wrk, &wrk->wpriv->nobjcore);
186
187 38353
        if (wrk->wpriv->nobjhead != NULL) {
188 72
                CHECK_OBJ(wrk->wpriv->nobjhead, OBJHEAD_MAGIC);
189 72
                Lck_Delete(&wrk->wpriv->nobjhead->mtx);
190 72
                FREE_OBJ(wrk->wpriv->nobjhead);
191 72
                wrk->stats->n_objecthead--;
192 72
        }
193 38353
        if (wrk->wpriv->nhashpriv != NULL) {
194
                /* XXX: If needed, add slinger method for this */
195 80
                free(wrk->wpriv->nhashpriv);
196 80
                wrk->wpriv->nhashpriv = NULL;
197 80
        }
198 38353
}
199
200
void
201 0
HSH_DeleteObjHead(const struct worker *wrk, struct objhead *oh)
202
{
203 0
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
204 0
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
205
206 0
        AZ(oh->refcnt);
207 0
        assert(VTAILQ_EMPTY(&oh->objcs));
208 0
        assert(VTAILQ_EMPTY(&oh->waitinglist));
209 0
        Lck_Delete(&oh->mtx);
210 0
        wrk->stats->n_objecthead--;
211 0
        FREE_OBJ(oh);
212 0
}
213
214
void
215 592634
HSH_AddString(struct req *req, void *ctx, const char *str)
216
{
217
218 592634
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
219 592634
        AN(ctx);
220 592634
        if (str != NULL) {
221 296300
                VSHA256_Update(ctx, str, strlen(str));
222 296300
                VSLbs(req->vsl, SLT_Hash, TOSTRAND(str));
223 296300
        } else
224 296334
                VSHA256_Update(ctx, &str, 1);
225 592634
}
226
227
/*---------------------------------------------------------------------
228
 * This is a debugging hack to enable testing of boundary conditions
229
 * in the hash algorithm.
230
 * We trap the first 9 different digests and translate them to different
231
 * digests with edge bit conditions
232
 */
233
234
static struct hsh_magiclist {
235
        unsigned char was[VSHA256_LEN];
236
        unsigned char now[VSHA256_LEN];
237
} hsh_magiclist[] = {
238
        { .now = {      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
242
        { .now = {      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } },
246
        { .now = {      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } },
250
        { .now = {      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
253
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40 } },
254
        { .now = {      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 } },
258
        { .now = {      0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
259
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
262
        { .now = {      0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
266
        { .now = {      0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
270
        { .now = {      0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
274
};
275
276
#define HSH_NMAGIC vcountof(hsh_magiclist)
277
278
static void
279 720
hsh_testmagic(void *result)
280
{
281
        size_t i, j;
282
        static size_t nused = 0;
283
284 3600
        for (i = 0; i < nused; i++)
285 3240
                if (!memcmp(hsh_magiclist[i].was, result, VSHA256_LEN))
286 360
                        break;
287 720
        if (i == nused && i < HSH_NMAGIC)
288 360
                memcpy(hsh_magiclist[nused++].was, result, VSHA256_LEN);
289 720
        if (i == nused)
290 0
                return;
291 720
        assert(i < HSH_NMAGIC);
292 720
        fprintf(stderr, "HASHMAGIC: <");
293 23760
        for (j = 0; j < VSHA256_LEN; j++)
294 23040
                fprintf(stderr, "%02x", ((unsigned char*)result)[j]);
295 720
        fprintf(stderr, "> -> <");
296 720
        memcpy(result, hsh_magiclist[i].now, VSHA256_LEN);
297 23760
        for (j = 0; j < VSHA256_LEN; j++)
298 23040
                fprintf(stderr, "%02x", ((unsigned char*)result)[j]);
299 720
        fprintf(stderr, ">\n");
300 720
}
301
302
/*---------------------------------------------------------------------
303
 * Insert an object which magically appears out of nowhere or, more likely,
304
 * comes off some persistent storage device.
305
 * Insert it with a reference held.
306
 */
307
308
void
309 680
HSH_Insert(struct worker *wrk, const void *digest, struct objcore *oc,
310
    struct ban *ban)
311
{
312
        struct objhead *oh;
313
        struct rush rush;
314
315 680
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
316 680
        CHECK_OBJ_NOTNULL(wrk->wpriv, WORKER_PRIV_MAGIC);
317 680
        AN(digest);
318 680
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
319 680
        AN(ban);
320 680
        AZ(oc->flags & OC_F_BUSY);
321 680
        AZ(oc->flags & OC_F_PRIVATE);
322 680
        assert(oc->refcnt == 1);
323 680
        INIT_OBJ(&rush, RUSH_MAGIC);
324
325 680
        hsh_prealloc(wrk);
326
327 680
        AN(wrk->wpriv->nobjhead);
328 680
        oh = hash->lookup(wrk, digest, &wrk->wpriv->nobjhead);
329 680
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
330 680
        Lck_AssertHeld(&oh->mtx);
331 680
        assert(oh->refcnt > 0);
332
333
        /* Mark object busy and insert (precreated) objcore in
334
           objecthead. The new object inherits our objhead reference. */
335 680
        oc->objhead = oh;
336 680
        VTAILQ_INSERT_TAIL(&oh->objcs, oc, hsh_list);
337 680
        EXP_RefNewObjcore(oc);
338 680
        Lck_Unlock(&oh->mtx);
339
340 680
        BAN_RefBan(oc, ban);
341 680
        AN(oc->ban);
342
343
        /* Move the object first in the oh list, unbusy it and run the
344
           waitinglist if necessary */
345 680
        Lck_Lock(&oh->mtx);
346 680
        VTAILQ_REMOVE(&oh->objcs, oc, hsh_list);
347 680
        VTAILQ_INSERT_HEAD(&oh->objcs, oc, hsh_list);
348 680
        if (!VTAILQ_EMPTY(&oh->waitinglist))
349 0
                hsh_rush1(wrk, oc, &rush);
350 680
        Lck_Unlock(&oh->mtx);
351 680
        hsh_rush2(wrk, &rush);
352
353 680
        EXP_Insert(wrk, oc);
354 680
}
355
356
/*---------------------------------------------------------------------
357
 */
358
359
static struct objcore *
360 60946
hsh_insert_busyobj(const struct worker *wrk, struct objhead *oh)
361
{
362
        struct objcore *oc;
363
364 60946
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
365 60946
        CHECK_OBJ_NOTNULL(wrk->wpriv, WORKER_PRIV_MAGIC);
366 60946
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
367 60946
        Lck_AssertHeld(&oh->mtx);
368
369 60946
        oc = wrk->wpriv->nobjcore;
370 60946
        wrk->wpriv->nobjcore = NULL;
371 60946
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
372
373 60946
        AZ(oc->flags & OC_F_BUSY);
374 60946
        oc->flags |= OC_F_BUSY;
375 60946
        oc->refcnt = 1;         /* Owned by busyobj */
376 60946
        oc->objhead = oh;
377 60946
        VTAILQ_INSERT_TAIL(&oh->objcs, oc, hsh_list);
378 60946
        return (oc);
379
}
380
381
/*---------------------------------------------------------------------
382
 */
383
384
static int
385 157144
hsh_vry_match(const struct req *req, struct objcore *oc, const uint8_t *vary)
386
{
387
388 157144
        if (req->hash_ignore_vary)
389 40
                return (1);
390 157104
        if (vary == NULL) {
391 157029
                if (! ObjHasAttr(req->wrk, oc, OA_VARY))
392 44150
                        return (1);
393 112879
                vary = ObjGetAttr(req->wrk, oc, OA_VARY, NULL);
394 112879
                AN(vary);
395 112879
        }
396 112954
        return (VRY_Match(req, vary));
397 157144
}
398
399
static unsigned
400 2199
hsh_rush_match(const struct req *req)
401
{
402
        struct objhead *oh;
403
        struct objcore *oc;
404
405 2199
        oc = req->objcore;
406 2199
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
407 2199
        assert(oc->refcnt > 0);
408
409 2199
        AZ(oc->flags & OC_F_BUSY);
410 2199
        AZ(oc->flags & OC_F_PRIVATE);
411 2199
        if (oc->flags & (OC_F_WITHDRAWN|OC_F_HFM|OC_F_HFP|OC_F_CANCEL|
412
            OC_F_FAILED))
413 479
                return (0);
414
415 1720
        if (req->vcf != NULL) /* NB: must operate under oh lock. */
416 0
                return (0);
417
418 1720
        oh = oc->objhead;
419 1720
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
420
421 1720
        return (hsh_vry_match(req, oc, NULL));
422 2199
}
423
424
/*---------------------------------------------------------------------
425
 */
426
427
enum lookup_e
428 106559
HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp)
429
{
430
        struct worker *wrk;
431
        struct objhead *oh;
432
        struct objcore *oc;
433
        struct objcore *exp_oc;
434
        const struct vcf_return *vr;
435
        vtim_real exp_t_origin;
436
        int busy_found;
437
        intmax_t boc_progress;
438 106559
        unsigned xid = 0;
439
        unsigned ban_checks;
440
        unsigned ban_any_variant;
441 106559
        float dttl = 0.0;
442
443 106559
        AN(ocp);
444 106559
        *ocp = NULL;
445 106559
        AN(bocp);
446 106559
        *bocp = NULL;
447
448 106559
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
449 106559
        wrk = req->wrk;
450 106559
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
451 106559
        CHECK_OBJ_NOTNULL(wrk->wpriv, WORKER_PRIV_MAGIC);
452 106559
        CHECK_OBJ_NOTNULL(req->http, HTTP_MAGIC);
453 106559
        CHECK_OBJ_ORNULL(req->objcore, OBJCORE_MAGIC);
454 106559
        CHECK_OBJ_ORNULL(req->vcf, VCF_MAGIC);
455 106559
        AN(hash);
456
457 106559
        hsh_prealloc(wrk);
458 106559
        if (DO_DEBUG(DBG_HASHEDGE))
459 720
                hsh_testmagic(req->digest);
460
461
        /*
462
         * When a req rushes off the waiting list, it brings an implicit
463
         * oh refcnt acquired at disembark time and an oc ref (with its
464
         * own distinct oh ref) acquired during rush hour.
465
         */
466
467 106559
        if (req->objcore != NULL && hsh_rush_match(req)) {
468 1640
                TAKE_OBJ_NOTNULL(oc, &req->objcore, OBJCORE_MAGIC);
469 1640
                *ocp = oc;
470 1640
                oh = oc->objhead;
471 1640
                Lck_Lock(&oh->mtx);
472 1640
                oc->hits++;
473 1640
                boc_progress = oc->boc == NULL ? -1 : oc->boc->fetched_so_far;
474 1640
                AN(hsh_deref_objhead_unlock(wrk, &oh, oc));
475 1640
                Req_LogHit(wrk, req, oc, boc_progress);
476
                /* NB: since this hit comes from the waiting list instead of
477
                 * a regular lookup, grace is not considered. The object is
478
                 * fresh in the context of the waiting list, even expired: it
479
                 * was successfully just [re]validated by a fetch task.
480
                 */
481 1640
                return (HSH_HIT);
482
        }
483
484 104919
        if (req->objcore != NULL) {
485 577
                oh = req->objcore->objhead;
486 577
                (void)HSH_DerefObjCore(wrk, &req->objcore);
487 577
                Lck_Lock(&oh->mtx);
488 577
        } else {
489 104342
                AN(wrk->wpriv->nobjhead);
490 104342
                oh = hash->lookup(wrk, req->digest, &wrk->wpriv->nobjhead);
491
        }
492
493 104919
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
494 104919
        Lck_AssertHeld(&oh->mtx);
495
496 104919
        if (req->hash_always_miss) {
497
                /* XXX: should we do predictive Vary in this case ? */
498
                /* Insert new objcore in objecthead and release mutex */
499 600
                *bocp = hsh_insert_busyobj(wrk, oh);
500
                /* NB: no deref of objhead, new object inherits reference */
501 600
                Lck_Unlock(&oh->mtx);
502 600
                return (HSH_MISS);
503
        }
504
505 104319
        assert(oh->refcnt > 0);
506 104319
        busy_found = 0;
507 104319
        exp_oc = NULL;
508 104319
        exp_t_origin = 0.0;
509 104319
        ban_checks = 0;
510 104319
        ban_any_variant = cache_param->ban_any_variant;
511 220976
        VTAILQ_FOREACH(oc, &oh->objcs, hsh_list) {
512
                /* Must be at least our own ref + the objcore we examine */
513 159671
                assert(oh->refcnt > 1);
514 159671
                CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
515 159671
                assert(oc->objhead == oh);
516 159671
                assert(oc->refcnt > 0);
517
518 159671
                if (oc->flags & OC_F_DYING)
519 0
                        continue;
520 159671
                if (oc->flags & OC_F_FAILED)
521 0
                        continue;
522
523 159671
                CHECK_OBJ_ORNULL(oc->boc, BOC_MAGIC);
524 159671
                if (oc->flags & OC_F_BUSY) {
525 2440
                        if (req->hash_ignore_busy)
526 40
                                continue;
527
528 2400
                        if (oc->boc && oc->boc->vary != NULL &&
529 75
                            !hsh_vry_match(req, oc, oc->boc->vary)) {
530 40
                                wrk->strangelove++;
531 40
                                continue;
532
                        }
533
534 2360
                        busy_found = 1;
535 2360
                        continue;
536
                }
537
538 157231
                if (oc->ttl <= 0.)
539 1880
                        continue;
540
541 155351
                if (ban_checks++ < ban_any_variant
542 155351
                    && BAN_CheckObject(wrk, oc, req)) {
543 0
                        oc->flags |= OC_F_DYING;
544 0
                        EXP_Remove(oc, NULL);
545 0
                        continue;
546
                }
547
548 155351
                if (!hsh_vry_match(req, oc, NULL)) {
549 105040
                        wrk->strangelove++;
550 105040
                        continue;
551
                }
552
553 50311
                if (ban_checks >= ban_any_variant
554 50311
                    && BAN_CheckObject(wrk, oc, req)) {
555 1360
                        oc->flags |= OC_F_DYING;
556 1360
                        EXP_Remove(oc, NULL);
557 1360
                        continue;
558
                }
559
560 48951
                if (req->vcf != NULL) {
561 320
                        vr = req->vcf->func(req, &oc, &exp_oc, 0);
562 320
                        if (vr == VCF_CONTINUE)
563 160
                                continue;
564 160
                        if (vr == VCF_MISS) {
565 120
                                oc = NULL;
566 120
                                break;
567
                        }
568 40
                        if (vr == VCF_HIT)
569 40
                                break;
570 0
                        assert(vr == VCF_DEFAULT);
571 0
                }
572
573 48631
                if (EXP_Ttl(req, oc) > req->t_req) {
574 42854
                        assert(oh->refcnt > 1);
575 42854
                        assert(oc->objhead == oh);
576 42854
                        break;
577
                }
578
579 5777
                if (EXP_Ttl(NULL, oc) <= req->t_req && /* ignore req.max_age */
580 5640
                    oc->t_origin > exp_t_origin) {
581
                        /* record the newest object */
582 5600
                        exp_oc = oc;
583 5600
                        exp_t_origin = oc->t_origin;
584 5600
                        assert(oh->refcnt > 1);
585 5600
                        assert(exp_oc->objhead == oh);
586 5600
                }
587 5777
        }
588
589 104319
        if (req->vcf != NULL)
590 240
                (void)req->vcf->func(req, &oc, &exp_oc, 1);
591
592 104319
        if (oc != NULL && oc->flags & OC_F_HFP) {
593 439
                xid = VXID(ObjGetXID(wrk, oc));
594 439
                dttl = EXP_Dttl(req, oc);
595 439
                AN(hsh_deref_objhead_unlock(wrk, &oh, oc));
596 439
                wrk->stats->cache_hitpass++;
597 439
                VSLb(req->vsl, SLT_HitPass, "%u %.6f", xid, dttl);
598 439
                return (HSH_HITPASS);
599
        }
600
601 103880
        if (oc != NULL) {
602 42494
                *ocp = oc;
603 42494
                oc->refcnt++;
604 42494
                if (oc->flags & OC_F_HFM) {
605 1280
                        xid = VXID(ObjGetXID(wrk, oc));
606 1280
                        dttl = EXP_Dttl(req, oc);
607 1280
                        *bocp = hsh_insert_busyobj(wrk, oh);
608 1280
                        Lck_Unlock(&oh->mtx);
609 1280
                        wrk->stats->cache_hitmiss++;
610 1280
                        VSLb(req->vsl, SLT_HitMiss, "%u %.6f", xid, dttl);
611 1280
                        return (HSH_HITMISS);
612
                }
613 41214
                oc->hits++;
614 41214
                boc_progress = oc->boc == NULL ? -1 : oc->boc->fetched_so_far;
615 41214
                AN(hsh_deref_objhead_unlock(wrk, &oh, oc));
616 41214
                Req_LogHit(wrk, req, oc, boc_progress);
617 41214
                return (HSH_HIT);
618
        }
619
620 61386
        if (exp_oc != NULL && exp_oc->flags & OC_F_HFM) {
621
                /*
622
                 * expired HFM ("grace/keep HFM")
623
                 *
624
                 * XXX should HFM objects actually have grace/keep ?
625
                 * XXX also:  why isn't *ocp = exp_oc ?
626
                 */
627 160
                xid = VXID(ObjGetXID(wrk, exp_oc));
628 160
                dttl = EXP_Dttl(req, exp_oc);
629 160
                *bocp = hsh_insert_busyobj(wrk, oh);
630 160
                Lck_Unlock(&oh->mtx);
631 160
                wrk->stats->cache_hitmiss++;
632 160
                VSLb(req->vsl, SLT_HitMiss, "%u %.6f", xid, dttl);
633 160
                return (HSH_HITMISS);
634
        }
635
636 61226
        if (exp_oc != NULL && exp_oc->boc != NULL)
637 200
                boc_progress = exp_oc->boc->fetched_so_far;
638
        else
639 61026
                boc_progress = -1;
640
641 61226
        if (!busy_found) {
642 58906
                *bocp = hsh_insert_busyobj(wrk, oh);
643
644 58906
                if (exp_oc != NULL) {
645 5240
                        exp_oc->refcnt++;
646 5240
                        *ocp = exp_oc;
647 5240
                        if (EXP_Ttl_grace(req, exp_oc) >= req->t_req) {
648 3760
                                exp_oc->hits++;
649 3760
                                Lck_Unlock(&oh->mtx);
650 3760
                                Req_LogHit(wrk, req, exp_oc, boc_progress);
651 3760
                                return (HSH_GRACE);
652
                        }
653 1480
                }
654 55146
                Lck_Unlock(&oh->mtx);
655 55146
                return (HSH_MISS);
656
        }
657
658 2320
        AN(busy_found);
659 2320
        if (exp_oc != NULL && EXP_Ttl_grace(req, exp_oc) >= req->t_req) {
660
                /* we do not wait on the busy object if in grace */
661 120
                exp_oc->refcnt++;
662 120
                *ocp = exp_oc;
663 120
                exp_oc->hits++;
664 120
                AN(hsh_deref_objhead_unlock(wrk, &oh, NULL));
665 120
                Req_LogHit(wrk, req, exp_oc, boc_progress);
666 120
                return (HSH_GRACE);
667
        }
668
669
        /* There are one or more busy objects, wait for them */
670 2200
        VTAILQ_INSERT_TAIL(&oh->waitinglist, req, w_list);
671
672 2200
        AZ(req->hash_ignore_busy);
673
674
        /*
675
         * The objhead reference is held by req while it is parked on the
676
         * waiting list. The oh pointer is taken back from the objcore that
677
         * triggers a rush of req off the waiting list.
678
         */
679 2200
        assert(oh->refcnt > 1);
680
681 2200
        req->wrk = NULL;
682 2200
        req->waitinglist_gen = oh->waitinglist_gen;
683
684 2200
        if (DO_DEBUG(DBG_WAITINGLIST))
685 880
                VSLb(req->vsl, SLT_Debug, "on waiting list <%p>", oh);
686
687 2200
        Lck_Unlock(&oh->mtx);
688
689 2200
        wrk->stats->busy_sleep++;
690 2200
        return (HSH_BUSY);
691 106559
}
692
693
/*---------------------------------------------------------------------
694
 * Pick the req's we are going to rush from the waiting list
695
 */
696
697
static void
698 4794
hsh_rush1(const struct worker *wrk, struct objcore *oc, struct rush *r)
699
{
700
        struct objhead *oh;
701
        struct req *req;
702
        int i, max;
703
704 4794
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
705 4794
        CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC);
706 4794
        CHECK_OBJ_NOTNULL(r, RUSH_MAGIC);
707 4794
        VTAILQ_INIT(&r->reqs);
708
709 4794
        if (oc == NULL)
710 40
                return;
711
712 4754
        oh = oc->objhead;
713 4754
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
714 4754
        Lck_AssertHeld(&oh->mtx);
715
716 4754
        AZ(oc->flags & OC_F_BUSY);
717 4754
        AZ(oc->flags & OC_F_PRIVATE);
718 4754
        max = cache_param->rush_exponent;
719 4754
        if (oc->flags & (OC_F_WITHDRAWN|OC_F_FAILED))
720 3146
                max = 1;
721 4754
        assert(max > 0);
722
723 4754
        if (oc->waitinglist_gen == 0) {
724 4514
                oc->waitinglist_gen = oh->waitinglist_gen;
725 4514
                oh->waitinglist_gen++;
726 4514
        }
727
728 6954
        for (i = 0; i < max; i++) {
729 6514
                req = VTAILQ_FIRST(&oh->waitinglist);
730 6514
                if (req == NULL)
731 4314
                        break;
732
733 2200
                CHECK_OBJ(req, REQ_MAGIC);
734
735
                /* NB: The waiting list is naturally sorted by generation.
736
                 *
737
                 * Because of the exponential nature of the rush, it is
738
                 * possible that new requests enter the waiting list before
739
                 * the rush for this oc completes. Because the OC_F_BUSY flag
740
                 * was cleared before the beginning of the rush, requests
741
                 * from a newer generation already got a chance to evaluate
742
                 * oc during a lookup and it didn't match their criteria.
743
                 *
744
                 * Therefore there's no point propagating the exponential
745
                 * rush of this oc when we see a newer generation.
746
                 */
747 2200
                if (req->waitinglist_gen > oc->waitinglist_gen)
748 0
                        break;
749
750 2200
                AZ(req->wrk);
751 2200
                VTAILQ_REMOVE(&oh->waitinglist, req, w_list);
752 2200
                VTAILQ_INSERT_TAIL(&r->reqs, req, w_list);
753 2200
                req->objcore = oc;
754 2200
                oc->refcnt++;
755 2200
                wrk->stats->busy_wakeup++;
756 2200
        }
757 4794
}
758
759
/*---------------------------------------------------------------------
760
 * Rush req's that came from waiting list.
761
 */
762
763
static void
764 124329
hsh_rush2(struct worker *wrk, struct rush *r)
765
{
766
        struct req *req;
767
768 124329
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
769 124329
        CHECK_OBJ_NOTNULL(r, RUSH_MAGIC);
770
771 126528
        while (!VTAILQ_EMPTY(&r->reqs)) {
772 2199
                req = VTAILQ_FIRST(&r->reqs);
773 2199
                CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
774 2199
                VTAILQ_REMOVE(&r->reqs, req, w_list);
775 2199
                DSL(DBG_WAITINGLIST, req->vsl->wid, "off waiting list");
776 2199
                if (req->transport->reembark != NULL) {
777
                        // For ESI includes
778 42
                        req->transport->reembark(wrk, req);
779 42
                } else {
780
                        /*
781
                         * We ignore the queue limits which apply to new
782
                         * requests because if we fail to reschedule there
783
                         * may be vmod_privs to cleanup and we need a proper
784
                         * workerthread for that.
785
                         */
786 2157
                        AZ(Pool_Task(req->sp->pool, req->task, TASK_QUEUE_RUSH));
787
                }
788
        }
789 124329
}
790
791
/*---------------------------------------------------------------------
792
 * Purge an entire objhead
793
 */
794
795
unsigned
796 880
HSH_Purge(struct worker *wrk, struct objhead *oh, vtim_real ttl_now,
797
    vtim_dur ttl, vtim_dur grace, vtim_dur keep)
798
{
799
        struct objcore *oc, *oc_nows[2], **ocp;
800 880
        unsigned i, j, n, n_max, total = 0;
801
        int is_purge;
802
803 880
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
804 880
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
805
806 880
        is_purge = (ttl == 0 && grace == 0 && keep == 0);
807 880
        n_max = WS_ReserveLumps(wrk->aws, sizeof *ocp);
808 880
        if (n_max < 2) {
809
                /* No space on the workspace. Give it a stack buffer of 2
810
                 * elements, which is the minimum for the algorithm
811
                 * below. */
812 0
                ocp = oc_nows;
813 0
                n_max = 2;
814 0
        } else
815 880
                ocp = WS_Reservation(wrk->aws);
816 880
        AN(ocp);
817
818
        /* Note: This algorithm uses OC references in the list as
819
         * bookmarks, in order to know how far into the list we were when
820
         * releasing the mutex partway through and want to resume
821
         * again. This relies on the list not being reordered while we are
822
         * not holding the mutex. The only place where that happens is in
823
         * HSH_Unbusy(), where an OC_F_BUSY OC is moved first in the
824
         * list. This does not cause problems because we skip OC_F_BUSY
825
         * OCs. */
826
827 880
        Lck_Lock(&oh->mtx);
828 880
        oc = VTAILQ_FIRST(&oh->objcs);
829 880
        n = 0;
830 920
        while (1) {
831 5360
                for (; n < n_max && oc != NULL; oc = VTAILQ_NEXT(oc, hsh_list))
832
                {
833 4440
                        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
834 4440
                        assert(oc->objhead == oh);
835 4440
                        if (oc->flags & OC_F_BUSY) {
836
                                /* We cannot purge busy objects here, because
837
                                 * their owners have special rights to them,
838
                                 * and may nuke them without concern for the
839
                                 * refcount, which by definition always must
840
                                 * be one, so they don't check. */
841 760
                                continue;
842
                        }
843 3680
                        if (oc->flags & OC_F_DYING)
844 0
                                continue;
845 3680
                        if (is_purge)
846 3280
                                oc->flags |= OC_F_DYING;
847 3680
                        oc->refcnt++;
848 3680
                        ocp[n++] = oc;
849 3680
                }
850
851 920
                Lck_Unlock(&oh->mtx);
852
853 920
                if (n == 0) {
854
                        /* No eligible objcores found. We are finished. */
855 160
                        break;
856
                }
857
858 760
                j = n;
859 760
                if (oc != NULL) {
860
                        /* There are more objects on the objhead that we
861
                         * have not yet looked at, but no more space on
862
                         * the objcore reference list. Do not process the
863
                         * last one, it will be used as the bookmark into
864
                         * the objcore list for the next iteration of the
865
                         * outer loop. */
866 40
                        j--;
867 40
                        assert(j >= 1); /* True because n_max >= 2 */
868 40
                }
869 4440
                for (i = 0; i < j; i++) {
870 3680
                        CHECK_OBJ_NOTNULL(ocp[i], OBJCORE_MAGIC);
871 3680
                        if (is_purge)
872 3280
                                EXP_Remove(ocp[i], NULL);
873
                        else
874 400
                                EXP_Reduce(ocp[i], ttl_now, ttl, grace, keep);
875 3680
                        (void)HSH_DerefObjCore(wrk, &ocp[i]);
876 3680
                        AZ(ocp[i]);
877 3680
                        total++;
878 3680
                }
879
880 760
                if (j == n) {
881
                        /* No bookmark set, that means we got to the end
882
                         * of the objcore list in the previous run and are
883
                         * finished. */
884 720
                        break;
885
                }
886
887 40
                Lck_Lock(&oh->mtx);
888
889
                /* Move the bookmark first and continue scanning the
890
                 * objcores */
891 40
                CHECK_OBJ_NOTNULL(ocp[j], OBJCORE_MAGIC);
892 40
                ocp[0] = ocp[j];
893 40
                n = 1;
894 40
                oc = VTAILQ_NEXT(ocp[0], hsh_list);
895 40
                CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC);
896
        }
897
898 880
        WS_Release(wrk->aws, 0);
899 880
        if (is_purge)
900 480
                Pool_PurgeStat(total);
901 880
        return (total);
902
}
903
904
/*---------------------------------------------------------------------
905
 * Fail an objcore
906
 */
907
908
void
909 2719
HSH_Fail(struct worker *wrk, struct objcore *oc)
910
{
911
        struct objhead *oh;
912
        struct rush rush;
913
914 2719
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
915 2719
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
916 2719
        CHECK_OBJ_NOTNULL(oc->boc, BOC_MAGIC);
917 2719
        oh = oc->objhead;
918 2719
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
919 2719
        INIT_OBJ(&rush, RUSH_MAGIC);
920
921
        /*
922
         * We either failed before the end of vcl_backend_response
923
         * and a cache miss has the busy bit, so that HSH_Lookup()
924
         * will not consider this oc, or an object hung off the oc
925
         * so that it can consider it.
926
         *
927
         * We can only fail an ongoing fetch in a backend context
928
         * so we can safely check the BOC state as it won't change
929
         * under our feet.
930
         */
931 2719
        if (oc->boc->state < BOS_STREAM)
932 2040
                assert(oc->flags & (OC_F_BUSY|OC_F_PRIVATE));
933
        else
934 679
                assert(oc->stobj->stevedore != NULL);
935
936 2719
        Lck_Lock(&oh->mtx);
937 2719
        oc->flags |= OC_F_FAILED;
938 2719
        if (oc->flags & OC_F_BUSY) {
939 1800
                oc->flags &= ~OC_F_BUSY;
940 1800
                hsh_rush1(wrk, oc, &rush);
941 1800
        }
942 2719
        Lck_Unlock(&oh->mtx);
943 2719
        hsh_rush2(wrk, &rush);
944 2719
}
945
946
/*---------------------------------------------------------------------
947
 * Mark a fetch we will not need as cancelled
948
 */
949
950
static void
951 14098
hsh_cancel(struct objcore *oc)
952
{
953
        struct objhead *oh;
954
955 14098
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
956 14098
        oh = oc->objhead;
957 14098
        CHECK_OBJ(oh, OBJHEAD_MAGIC);
958
959 14098
        Lck_Lock(&oh->mtx);
960 14098
        oc->flags |= OC_F_CANCEL;
961 14098
        Lck_Unlock(&oh->mtx);
962 14098
}
963
964
/*---------------------------------------------------------------------
965
 * Cancel a fetch when the client does not need it any more
966
 */
967
968
void
969 153777
HSH_Cancel(struct worker *wrk, struct objcore *oc, struct boc *boc)
970
{
971 153777
        struct boc *bocref = NULL;
972
973 153777
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
974
975 153777
        if ((oc->flags & OC_F_TRANSIENT) == 0)
976 97777
                return;
977
978
        /*
979
         * NB: we use two distinct variables to only release the reference if
980
         * we had to acquire one. The caller-provided boc is optional.
981
         */
982 56000
        if (boc == NULL)
983 42015
                bocref = boc = HSH_RefBoc(oc);
984
985 56000
        CHECK_OBJ_ORNULL(boc, BOC_MAGIC);
986
987 56000
        if (oc->flags & OC_F_HFP)
988 877
                AN(oc->flags & OC_F_HFM);
989
990 56000
        if (boc != NULL) {
991 14099
                hsh_cancel(oc);
992 14099
                ObjWaitState(oc, BOS_FINISHED);
993 14099
        }
994
995 56000
        if (bocref != NULL)
996 119
                HSH_DerefBoc(wrk, oc);
997
998 56000
        ObjSlim(wrk, oc);
999 153777
}
1000
1001
/*---------------------------------------------------------------------
1002
 * Withdraw an objcore that will not proceed with a fetch.
1003
 */
1004
1005
void
1006 1346
HSH_Withdraw(struct worker *wrk, struct objcore **ocp)
1007
{
1008
        struct objhead *oh;
1009
        struct objcore *oc;
1010
        struct rush rush;
1011
1012 1346
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1013 1346
        TAKE_OBJ_NOTNULL(oc, ocp, OBJCORE_MAGIC);
1014 1346
        INIT_OBJ(&rush, RUSH_MAGIC);
1015
1016 1346
        oh = oc->objhead;
1017 1346
        CHECK_OBJ(oh, OBJHEAD_MAGIC);
1018
1019 1346
        Lck_Lock(&oh->mtx);
1020 1346
        AZ(oc->stobj->stevedore);
1021 1346
        AN(oc->flags & OC_F_BUSY);
1022 1346
        assert(oc->refcnt == 1);
1023 1346
        assert(oh->refcnt > 0);
1024 1346
        oc->flags &= ~OC_F_BUSY;
1025 1346
        oc->flags |= OC_F_WITHDRAWN;
1026 1346
        hsh_rush1(wrk, oc, &rush); /* grabs up to 1 oc ref */
1027 1346
        assert(hsh_deref_objcore_unlock(wrk, &oc) <= 1);
1028
1029 1346
        hsh_rush2(wrk, &rush);
1030 1346
}
1031
1032
/*---------------------------------------------------------------------
1033
 * Unbusy an objcore when the object is completely fetched.
1034
 */
1035
1036
void
1037 88920
HSH_Unbusy(struct worker *wrk, struct objcore *oc)
1038
{
1039
        struct objhead *oh;
1040
        struct rush rush;
1041
1042 88920
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1043 88920
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
1044 88920
        CHECK_OBJ_NOTNULL(oc->boc, BOC_MAGIC);
1045
1046 88920
        oh = oc->objhead;
1047 88920
        CHECK_OBJ(oh, OBJHEAD_MAGIC);
1048
1049 88920
        AN(oc->stobj->stevedore);
1050 88920
        assert(oh->refcnt > 0);
1051 88920
        assert(oc->refcnt > 0);
1052
1053 88920
        if (oc->flags & OC_F_PRIVATE) {
1054 31160
                AZ(oc->flags & OC_F_BUSY);
1055 31160
                return;
1056
        }
1057
1058 57760
        AN(oc->flags & OC_F_BUSY);
1059 57760
        INIT_OBJ(&rush, RUSH_MAGIC);
1060
1061 57760
        BAN_NewObjCore(oc);
1062 57760
        AN(oc->ban);
1063
1064
        /* XXX: pretouch neighbors on oh->objcs to prevent page-on under mtx */
1065 57760
        Lck_Lock(&oh->mtx);
1066 57760
        assert(oh->refcnt > 0);
1067 57760
        assert(oc->refcnt > 0);
1068 57760
        EXP_RefNewObjcore(oc); /* Takes a ref for expiry */
1069
        /* XXX: strictly speaking, we should sort in Date: order. */
1070 57760
        VTAILQ_REMOVE(&oh->objcs, oc, hsh_list);
1071 57760
        VTAILQ_INSERT_HEAD(&oh->objcs, oc, hsh_list);
1072 57760
        oc->flags &= ~OC_F_BUSY;
1073 57760
        if (!VTAILQ_EMPTY(&oh->waitinglist)) {
1074 1351
                assert(oh->refcnt > 1);
1075 1351
                hsh_rush1(wrk, oc, &rush);
1076 1351
        }
1077 57760
        Lck_Unlock(&oh->mtx);
1078 57760
        EXP_Insert(wrk, oc);
1079 57760
        hsh_rush2(wrk, &rush);
1080 88920
}
1081
1082
/*====================================================================
1083
 * HSH_Kill()
1084
 *
1085
 * It's dead Jim, kick it...
1086
 */
1087
1088
void
1089 9439
HSH_Kill(struct objcore *oc)
1090
{
1091
1092 9439
        HSH_Replace(oc, NULL);
1093 9439
}
1094
1095
void
1096 12479
HSH_Replace(struct objcore *oc, const struct objcore *new_oc)
1097
{
1098
1099 12479
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
1100 12479
        CHECK_OBJ_NOTNULL(oc->objhead, OBJHEAD_MAGIC);
1101 12479
        if (new_oc != NULL) {
1102 3040
                CHECK_OBJ(new_oc, OBJCORE_MAGIC);
1103 3040
                assert(oc->objhead == new_oc->objhead);
1104 3040
        }
1105
1106 12479
        Lck_Lock(&oc->objhead->mtx);
1107 12479
        oc->flags |= OC_F_DYING;
1108 12479
        Lck_Unlock(&oc->objhead->mtx);
1109 12479
        EXP_Remove(oc, new_oc);
1110 12479
}
1111
1112
/*====================================================================
1113
 * HSH_Snipe()
1114
 *
1115
 * If objcore is idle, gain a ref and mark it dead.
1116
 */
1117
1118
int
1119 440
HSH_Snipe(const struct worker *wrk, struct objcore *oc)
1120
{
1121 440
        int retval = 0;
1122
1123 440
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1124 440
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
1125 440
        CHECK_OBJ_NOTNULL(oc->objhead, OBJHEAD_MAGIC);
1126
1127 440
        if (oc->refcnt == 1 && !Lck_Trylock(&oc->objhead->mtx)) {
1128 440
                if (oc->refcnt == 1 && !(oc->flags & OC_F_DYING)) {
1129 440
                        oc->flags |= OC_F_DYING;
1130 440
                        oc->refcnt++;
1131 440
                        retval = 1;
1132 440
                }
1133 440
                Lck_Unlock(&oc->objhead->mtx);
1134 440
        }
1135 440
        if (retval)
1136 440
                EXP_Remove(oc, NULL);
1137 440
        return (retval);
1138
}
1139
1140
1141
/*---------------------------------------------------------------------
1142
 * Gain a reference on an objcore
1143
 */
1144
1145
void
1146 98118
HSH_Ref(struct objcore *oc)
1147
{
1148
        struct objhead *oh;
1149
1150 98118
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
1151 98118
        oh = oc->objhead;
1152 98118
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
1153 98118
        Lck_Lock(&oh->mtx);
1154 98118
        assert(oc->refcnt > 0);
1155 98118
        oc->refcnt++;
1156 98118
        Lck_Unlock(&oh->mtx);
1157 98118
}
1158
1159
/*---------------------------------------------------------------------
1160
 * Gain a reference on the busyobj, if the objcore has one
1161
 */
1162
1163
struct boc *
1164 384050
HSH_RefBoc(const struct objcore *oc)
1165
{
1166
        struct objhead *oh;
1167
        struct boc *boc;
1168
1169 384050
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
1170 384050
        oh = oc->objhead;
1171 384050
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
1172 384050
        if (oc->boc == NULL)
1173 225815
                return (NULL);
1174 158235
        Lck_Lock(&oh->mtx);
1175 158235
        assert(oc->refcnt > 0);
1176 158235
        boc = oc->boc;
1177 158235
        CHECK_OBJ_ORNULL(boc, BOC_MAGIC);
1178 158231
        if (boc != NULL) {
1179 158186
                assert(boc->refcount > 0);
1180 158186
                if (boc->state < BOS_FINISHED)
1181 157250
                        boc->refcount++;
1182
                else
1183 936
                        boc = NULL;
1184 158186
        }
1185 158231
        Lck_Unlock(&oh->mtx);
1186 158231
        return (boc);
1187 384046
}
1188
1189
void
1190 274132
HSH_DerefBoc(struct worker *wrk, struct objcore *oc)
1191
{
1192
        struct boc *boc;
1193
        unsigned r;
1194
1195 274132
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1196 274132
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
1197 274132
        boc = oc->boc;
1198 274132
        CHECK_OBJ_NOTNULL(boc, BOC_MAGIC);
1199 274132
        Lck_Lock(&oc->objhead->mtx);
1200 274132
        assert(oc->refcnt > 0);
1201 274132
        assert(boc->refcount > 0);
1202 274132
        r = --boc->refcount;
1203 274132
        if (r == 0)
1204 116916
                oc->boc = NULL;
1205 274132
        Lck_Unlock(&oc->objhead->mtx);
1206 274132
        if (r == 0)
1207 116917
                ObjBocDone(wrk, oc, &boc);
1208 274132
}
1209
1210
/*--------------------------------------------------------------------
1211
 * Dereference objcore
1212
 *
1213
 * Returns zero if target was destroyed.
1214
 */
1215
1216
int
1217 285158
HSH_DerefObjCore(struct worker *wrk, struct objcore **ocp)
1218
{
1219
        struct objcore *oc;
1220
        struct objhead *oh;
1221
1222 285158
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1223 285158
        TAKE_OBJ_NOTNULL(oc, ocp, OBJCORE_MAGIC);
1224 285158
        assert(oc->refcnt > 0);
1225
1226 285158
        oh = oc->objhead;
1227 285158
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
1228
1229 285158
        Lck_Lock(&oh->mtx);
1230 285158
        return (hsh_deref_objcore_unlock(wrk, &oc));
1231
}
1232
1233
static int
1234 286622
hsh_deref_objcore_unlock(struct worker *wrk, struct objcore **ocp)
1235
{
1236
        struct objcore *oc;
1237
        struct objhead *oh;
1238
        int r;
1239
1240 286622
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1241 286622
        TAKE_OBJ_NOTNULL(oc, ocp, OBJCORE_MAGIC);
1242 286622
        assert(oc->refcnt > 0);
1243
1244 286622
        oh = oc->objhead;
1245 286622
        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
1246
1247 286622
        Lck_AssertHeld(&oh->mtx);
1248 286622
        assert(oh->refcnt > 0);
1249 286622
        r = --oc->refcnt;
1250 286622
        if (!r)
1251 75129
                VTAILQ_REMOVE(&oh->objcs, oc, hsh_list);
1252 286622
        Lck_Unlock(&oh->mtx);
1253 286622
        if (r != 0)
1254 211493
                return (r);
1255
1256 75129
        AZ(oc->flags & OC_F_BUSY);
1257 75129
        AZ(oc->exp_flags);
1258
1259 75129
        BAN_DestroyObj(oc);
1260 75129
        AZ(oc->ban);
1261
1262 75129
        if (oc->stobj->stevedore != NULL)
1263 71662
                ObjFreeObj(wrk, oc);
1264 75129
        ObjDestroy(wrk, &oc);
1265
1266
        /* Drop our ref on the objhead */
1267 75129
        assert(oh->refcnt > 0);
1268 75129
        (void)hsh_deref_objhead(wrk, &oh);
1269 75129
        return (0);
1270 286622
}
1271
1272
static int
1273 118545
hsh_deref_objhead_unlock(struct worker *wrk, struct objhead **poh,
1274
    struct objcore *oc)
1275
{
1276
        struct objhead *oh;
1277
        struct rush rush;
1278
        int r;
1279
1280 118545
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1281 118545
        TAKE_OBJ_NOTNULL(oh, poh, OBJHEAD_MAGIC);
1282
1283 118545
        Lck_AssertHeld(&oh->mtx);
1284
1285 118545
        if (oh >= private_ohs && oh < private_ohs + vcountof(private_ohs)) {
1286 56718
                assert(VTAILQ_EMPTY(&oh->waitinglist));
1287 56718
                assert(oh->refcnt > 1);
1288 56718
                oh->refcnt--;
1289 56718
                Lck_Unlock(&oh->mtx);
1290 56718
                return (1);
1291
        }
1292
1293
        //lint --e{661}
1294
        //lint -specific(-e661)
1295
        //
1296
        // because of the static array, flexelint thinks that all ohs were from
1297
        // the static array :( the above suppression applies to the remainder of
1298
        // this function body and specific walks involving this function
1299
1300 61827
        INIT_OBJ(&rush, RUSH_MAGIC);
1301 61825
        if (!VTAILQ_EMPTY(&oh->waitinglist)) {
1302 297
                assert(oh->refcnt > 1);
1303 297
                hsh_rush1(wrk, oc, &rush);
1304 297
        }
1305
1306 61825
        if (oh->refcnt == 1)
1307 7237
                assert(VTAILQ_EMPTY(&oh->waitinglist));
1308
1309 61825
        assert(oh->refcnt > 0);
1310 61825
        r = hash->deref(wrk, oh); /* Unlocks oh->mtx */
1311 61825
        hsh_rush2(wrk, &rush);
1312 61825
        return (r);
1313 118543
}
1314
1315
static int
1316 75130
hsh_deref_objhead(struct worker *wrk, struct objhead **poh)
1317
{
1318
        struct objhead *oh;
1319
1320 75130
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1321 75130
        TAKE_OBJ_NOTNULL(oh, poh, OBJHEAD_MAGIC);
1322
1323 75130
        Lck_Lock(&oh->mtx);
1324 75130
        return (hsh_deref_objhead_unlock(wrk, &oh, NULL));
1325
}
1326
1327
void
1328 37932
HSH_Init(const struct hash_slinger *slinger)
1329
{
1330
1331 37932
        assert(DIGEST_LEN == VSHA256_LEN);      /* avoid #include pollution */
1332 37932
        hash = slinger;
1333 37932
        if (hash->start != NULL)
1334 37932
                hash->start();
1335 4893228
        for (struct objhead *oh = private_ohs;
1336 4893228
            oh < private_ohs + vcountof(private_ohs);
1337 4855296
            oh++) {
1338 4855296
                hsh_initobjhead(oh);
1339 4855296
                assert(oh->refcnt == 1);
1340 4855296
        }
1341 37932
}