Commit aaff00e8 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Convert the (persistent) stevedores tail reference into a proper "hold"

on the ban lurker not starting.

Move cache_hash's access to bans into cache_priv.h
parent 756fbe23
...@@ -655,18 +655,19 @@ struct sess { ...@@ -655,18 +655,19 @@ struct sess {
typedef enum htc_status_e htc_complete_f(struct http_conn *); typedef enum htc_status_e htc_complete_f(struct http_conn *);
/* cache_ban.c */ /* cache_ban.c */
/* for constructing bans */
struct ban *BAN_New(void); struct ban *BAN_New(void);
int BAN_AddTest(struct ban *, const char *, const char *, const char *); int BAN_AddTest(struct ban *, const char *, const char *, const char *);
void BAN_Free(struct ban *b); void BAN_Free(struct ban *b);
char *BAN_Insert(struct ban *b); char *BAN_Insert(struct ban *b);
void BAN_Free_Errormsg(char *); void BAN_Free_Errormsg(char *);
void BAN_NewObjCore(struct objcore *oc);
void BAN_DestroyObj(struct objcore *oc); /* for stevedoes resurrecting bans */
int BAN_CheckObject(struct worker *, struct objcore *, struct req *); void BAN_Hold(void);
void BAN_Release(void);
void BAN_Reload(const uint8_t *ban, unsigned len); void BAN_Reload(const uint8_t *ban, unsigned len);
struct ban *BAN_TailRef(void); struct ban *BAN_RefBan(struct objcore *oc, double t0);
struct ban *BAN_RefBan(struct objcore *oc, double t0, const struct ban *tail);
void BAN_TailDeref(struct ban **ban);
double BAN_Time(const struct ban *ban); double BAN_Time(const struct ban *ban);
/* cache_busyobj.c */ /* cache_busyobj.c */
......
...@@ -43,12 +43,13 @@ ...@@ -43,12 +43,13 @@
#include "vtim.h" #include "vtim.h"
struct lock ban_mtx; struct lock ban_mtx;
int ban_shutdown = 0; int ban_shutdown;
struct banhead_s ban_head = VTAILQ_HEAD_INITIALIZER(ban_head); struct banhead_s ban_head = VTAILQ_HEAD_INITIALIZER(ban_head);
struct ban * volatile ban_start; struct ban * volatile ban_start;
static struct ban *ban_magic; static struct ban *ban_magic;
static pthread_t ban_thread; static pthread_t ban_thread;
static int ban_holds;
struct ban_test { struct ban_test {
uint8_t arg1; uint8_t arg1;
...@@ -121,34 +122,31 @@ BAN_Free(struct ban *b) ...@@ -121,34 +122,31 @@ BAN_Free(struct ban *b)
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Get & Release a tail reference, used to hold the list stable for * Get/release holds which prevent the ban_lurker from starting.
* traversals etc. * Holds are held while stevedores load zombie objects.
*/ */
struct ban * void
BAN_TailRef(void) BAN_Hold(void)
{ {
struct ban *b;
ASSERT_CLI();
Lck_Lock(&ban_mtx); Lck_Lock(&ban_mtx);
b = VTAILQ_LAST(&ban_head, banhead_s); /* Once holds are released, we allow no more */
AN(b); assert(ban_holds > 0);
b->refcount++; ban_holds++;
Lck_Unlock(&ban_mtx); Lck_Unlock(&ban_mtx);
return (b);
} }
void void
BAN_TailDeref(struct ban **bb) BAN_Release(void)
{ {
struct ban *b;
b = *bb;
*bb = NULL;
Lck_Lock(&ban_mtx); Lck_Lock(&ban_mtx);
b->refcount--; assert(ban_holds > 0);
ban_holds--;
Lck_Unlock(&ban_mtx); Lck_Unlock(&ban_mtx);
if (ban_holds == 0)
WRK_BgThread(&ban_thread, "ban-lurker", ban_lurker, NULL);
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -549,11 +547,11 @@ BAN_DestroyObj(struct objcore *oc) ...@@ -549,11 +547,11 @@ BAN_DestroyObj(struct objcore *oc)
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Find and/or Grab a reference to an objects ban based on timestamp * Find and/or Grab a reference to an objects ban based on timestamp
* Assume we hold a TailRef, so list traversal is safe. * Assume we have a BAN_Hold, so list traversal is safe.
*/ */
struct ban * struct ban *
BAN_RefBan(struct objcore *oc, double t0, const struct ban *tail) BAN_RefBan(struct objcore *oc, double t0)
{ {
struct ban *b; struct ban *b;
double t1 = 0; double t1 = 0;
...@@ -562,12 +560,11 @@ BAN_RefBan(struct objcore *oc, double t0, const struct ban *tail) ...@@ -562,12 +560,11 @@ BAN_RefBan(struct objcore *oc, double t0, const struct ban *tail)
t1 = ban_time(b->spec); t1 = ban_time(b->spec);
if (t1 <= t0) if (t1 <= t0)
break; break;
if (b == tail)
break;
} }
AN(b); AN(b);
assert(t1 == t0); assert(t1 == t0);
Lck_Lock(&ban_mtx); Lck_Lock(&ban_mtx);
assert(ban_holds > 0);
b->refcount++; b->refcount++;
VTAILQ_INSERT_TAIL(&b->objcore, oc, ban_list); VTAILQ_INSERT_TAIL(&b->objcore, oc, ban_list);
Lck_Unlock(&ban_mtx); Lck_Unlock(&ban_mtx);
...@@ -966,7 +963,10 @@ ccf_ban_list(struct cli *cli, const char * const *av, void *priv) ...@@ -966,7 +963,10 @@ ccf_ban_list(struct cli *cli, const char * const *av, void *priv)
(void)priv; (void)priv;
/* Get a reference so we are safe to traverse the list */ /* Get a reference so we are safe to traverse the list */
bl = BAN_TailRef(); Lck_Lock(&ban_mtx);
bl = VTAILQ_LAST(&ban_head, banhead_s);
bl->refcount++;
Lck_Unlock(&ban_mtx);
VCLI_Out(cli, "Present bans:\n"); VCLI_Out(cli, "Present bans:\n");
VTAILQ_FOREACH(b, &ban_head, list) { VTAILQ_FOREACH(b, &ban_head, list) {
...@@ -994,7 +994,9 @@ ccf_ban_list(struct cli *cli, const char * const *av, void *priv) ...@@ -994,7 +994,9 @@ ccf_ban_list(struct cli *cli, const char * const *av, void *priv)
} }
} }
BAN_TailDeref(&bl); Lck_Lock(&ban_mtx);
bl->refcount--;
Lck_Unlock(&ban_mtx);
} }
static struct cli_proto ban_cmds[] = { static struct cli_proto ban_cmds[] = {
...@@ -1010,7 +1012,8 @@ void ...@@ -1010,7 +1012,8 @@ void
BAN_Compile(void) BAN_Compile(void)
{ {
/* All bans have been read from all persistent stevedores. Export /*
* All bans have been read from all persistent stevedores. Export
* the compiled list * the compiled list
*/ */
...@@ -1027,10 +1030,9 @@ BAN_Compile(void) ...@@ -1027,10 +1030,9 @@ BAN_Compile(void)
Lck_Unlock(&ban_mtx); Lck_Unlock(&ban_mtx);
ban_start = VTAILQ_FIRST(&ban_head); ban_start = VTAILQ_FIRST(&ban_head);
WRK_BgThread(&ban_thread, "ban-lurker", ban_lurker, NULL); BAN_Release();
} }
void void
BAN_Init(void) BAN_Init(void)
{ {
...@@ -1043,6 +1045,7 @@ BAN_Init(void) ...@@ -1043,6 +1045,7 @@ BAN_Init(void)
AZ(BAN_Insert(ban_magic)); AZ(BAN_Insert(ban_magic));
Lck_Lock(&ban_mtx); Lck_Lock(&ban_mtx);
ban_mark_completed(ban_magic); ban_mark_completed(ban_magic);
ban_holds = 1;
Lck_Unlock(&ban_mtx); Lck_Unlock(&ban_mtx);
} }
......
...@@ -57,11 +57,19 @@ void VBE_Poll(void); ...@@ -57,11 +57,19 @@ void VBE_Poll(void);
/* cache_backend_poll.c */ /* cache_backend_poll.c */
void VBP_Init(void); void VBP_Init(void);
/* cache_ban.c */ /* == cache_ban.c == */
/* From cache_main.c */
void BAN_Init(void); void BAN_Init(void);
void BAN_Compile(void); void BAN_Compile(void);
void BAN_Shutdown(void); void BAN_Shutdown(void);
/* From cache_hash.c */
void BAN_NewObjCore(struct objcore *oc);
void BAN_DestroyObj(struct objcore *oc);
int BAN_CheckObject(struct worker *, struct objcore *, struct req *);
/* cache_busyobj.c */ /* cache_busyobj.c */
void VBO_Init(void); void VBO_Init(void);
......
...@@ -287,8 +287,7 @@ smp_thread(struct worker *wrk, void *priv) ...@@ -287,8 +287,7 @@ smp_thread(struct worker *wrk, void *priv)
smp_load_seg(wrk, sc, sg); smp_load_seg(wrk, sc, sg);
sc->flags |= SMP_SC_LOADED; sc->flags |= SMP_SC_LOADED;
BAN_TailDeref(&sc->tailban); BAN_Release();
AZ(sc->tailban);
printf("Silo completely loaded\n"); printf("Silo completely loaded\n");
/* Housekeeping loop */ /* Housekeeping loop */
...@@ -358,8 +357,7 @@ smp_open(const struct stevedore *st) ...@@ -358,8 +357,7 @@ smp_open(const struct stevedore *st)
* has loaded all objects, so we can be sure that all of our * has loaded all objects, so we can be sure that all of our
* proto-bans survive until then. * proto-bans survive until then.
*/ */
sc->tailban = BAN_TailRef(); BAN_Hold();
AN(sc->tailban);
/* XXX: save segments to ensure consistency between seg1 & seg2 ? */ /* XXX: save segments to ensure consistency between seg1 & seg2 ? */
......
...@@ -253,8 +253,6 @@ struct smp_sc { ...@@ -253,8 +253,6 @@ struct smp_sc {
struct smp_signspace seg1; struct smp_signspace seg1;
struct smp_signspace seg2; struct smp_signspace seg2;
struct ban *tailban;
struct lock mtx; struct lock mtx;
/* Cleaner metrics */ /* Cleaner metrics */
......
...@@ -163,7 +163,7 @@ smp_load_seg(struct worker *wrk, const struct smp_sc *sc, ...@@ -163,7 +163,7 @@ smp_load_seg(struct worker *wrk, const struct smp_sc *sc,
oc->stobj->stevedore = sc->parent; oc->stobj->stevedore = sc->parent;
smp_init_oc(oc, sg, no); smp_init_oc(oc, sg, no);
oc->stobj->priv2 |= NEED_FIXUP; oc->stobj->priv2 |= NEED_FIXUP;
oc->ban = BAN_RefBan(oc, so->ban, sc->tailban); oc->ban = BAN_RefBan(oc, so->ban);
HSH_Insert(wrk, so->hash, oc); HSH_Insert(wrk, so->hash, oc);
oc->exp = so->exp; oc->exp = so->exp;
sg->nobj++; sg->nobj++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment