Decide a race between obj_get() and lru

we only set stobj->priv after returning from obj_get(), so
assert(oc->stobj->priv == fco) could trigger in the lru thread.

We now set the priv right before inserting into LRU.
parent 2235fc09
......@@ -4893,6 +4893,10 @@ struct objcore **ocp, uintptr_t priv2, unsigned crit)
AN(fcs->fco_infdb);
fcs->disk_seg = &fdo->fdo_fds;
fellow_cache_seg_transition_locked(lcb, fcs, fcs->state, FCO_INCORE);
if (fco->oc) {
AZ(fco->oc->stobj->priv);
fco->oc->stobj->priv = fco;
}
fellow_cache_lru_chgbatch_apply(lcb);
if (fcs->refcnt > 1)
AZ(pthread_cond_broadcast(&fco->cond));
......@@ -5494,12 +5498,11 @@ test_fellow_cache_obj_get(struct fellow_cache *fc, uintptr_t priv2,
struct objcore *oc1, *toc, ocmem[1];
int injcount;
INIT_OBJ(ocmem, OBJCORE_MAGIC);
DBG("expect %s", expect == incache ? "incache" : "notincache");
// baseline, no injection
fc_inj_reset();
INIT_OBJ(ocmem, OBJCORE_MAGIC);
toc = ocmem;
fcr = fellow_cache_obj_get(fc, &toc, priv2, 0);
if (fcr.status != fcr_ok) {
......@@ -5524,6 +5527,7 @@ test_fellow_cache_obj_get(struct fellow_cache *fc, uintptr_t priv2,
AN(injcount);
while (injcount) {
fc_inj_set(injcount);
INIT_OBJ(ocmem, OBJCORE_MAGIC);
toc = ocmem;
fcr = fellow_cache_obj_get(fc, &toc, priv2, 0);
AN(toc);
......@@ -5535,6 +5539,7 @@ test_fellow_cache_obj_get(struct fellow_cache *fc, uintptr_t priv2,
DBG("fco1e %p ref %u", fco, FCO_REFCNT(fco));
fc_inj_reset();
INIT_OBJ(ocmem, OBJCORE_MAGIC);
toc = ocmem;
fcr = fellow_cache_obj_get(fc, &toc, priv2, 0);
DBG("fco2 %p ref %u", fco, FCO_REFCNT(fco));
......@@ -5558,8 +5563,6 @@ static void test_fellow_cache_obj_iter_final(
struct fcscursor c;
int injcount;
INIT_OBJ(ocmem, OBJCORE_MAGIC);
AN(fcop);
AN(*fcop);
......@@ -5599,6 +5602,7 @@ static void test_fellow_cache_obj_iter_final(
DBG("injcount %d", injcount);
fc_inj_set(0);
INIT_OBJ(ocmem, OBJCORE_MAGIC);
toc = ocmem;
fcr = fellow_cache_obj_get(fc, &toc, priv2, 0);
assert(fcr.status == fcr_ok);
......@@ -5621,6 +5625,7 @@ static void test_fellow_cache_obj_iter_final(
// get back the original number of references
for (u = 0; u < refcnt; u++) {
INIT_OBJ(ocmem, OBJCORE_MAGIC);
toc = ocmem;
fcr = fellow_cache_obj_get(fc, &toc, priv2, 0);
assert(fcr.status == fcr_ok);
......
......@@ -420,7 +420,7 @@ stvfe_dskoc_fco(struct worker *wrk,
struct objcore *refoc;
struct fcoc fcoc = {0};
uint64_t *counter;
void *priv, *old;
void *priv;
CHECK_OBJ_NOTNULL(stvfe, STVFE_MAGIC);
AN(oc->stobj->priv2);
......@@ -477,9 +477,7 @@ stvfe_dskoc_fco(struct worker *wrk,
goto out;
}
/* fellow_cache_obj_get() decides the race already */
old = __atomic_exchange_n(&oc->stobj->priv, fcoc.fco, __ATOMIC_SEQ_CST);
AZ(old);
assert(fcoc.fco == oc->stobj->priv);
assert(stv == stvfe->dskstv);
oc->stobj->stevedore = stvfe->memstv;
......
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