Handle a race between stvfe_mutate() and stvfe_dskoc_fco()

In stvfe_dskoc_fco() we change the oc's stevedore to memstv only
_after_ we have taken a refernce via fellow_cache_obj_get() and thus
potentially put the fco onto the lru list.

This order is important, because other requests racing on
stvfe_dskoc_fco() need to also go through fellow_cache_obj_get() until
the memstv object has been established for real.

Yet this opens a window for a window where an fco is on LRU with
oc->stobj->stevedore still set to dskstv, even without dirty reads,
and even more so with dirty reads.

Because any additional synchronization here could kill performance, we
handle this outdated read in stvfe_mutate by not touching the object
(yet). It will be hit the next time we iterate the LRU list.

Fixes #13, hopefully.
parent 51cc35b3
......@@ -1615,6 +1615,11 @@ stvfe_mutate(struct worker *wrk, struct objcore *oc)
stv = oc_stv(wrk, oc);
stvfe = stv_stvfe(stv);
if (stv != stvfe->memstv) {
AZ(retval);
goto unlock;
}
assert_memstv(stvfe, stv);
AN(oc->stobj->priv);
AN(oc->stobj->priv2);
......@@ -1629,6 +1634,7 @@ stvfe_mutate(struct worker *wrk, struct objcore *oc)
wrk->stats->n_vampireobject++;
wrk->stats->n_object--;
}
unlock:
Lck_Unlock(&oh->mtx);
}
......
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