ref: 5e6f3db0d764ef8774e880c96e95f805df6a09e9
parent: 0db5d2bdd6b6cbdd24baea0a369c565506c8cc7f
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jun 8 12:02:11 EDT 2024
gefs: fix deadlock between epochclean and truncwait epochclean should not hold the mutation lock, which should allow procs within an epoch to make progress and end their epoch.
--- a/sys/src/cmd/gefs/fs.c
+++ b/sys/src/cmd/gefs/fs.c
@@ -2353,8 +2353,8 @@
}
assert(estacksz() == 0);
epochend(id);
- epochclean();
qunlock(&fs->mutlk);
+ epochclean();
if(a != nil)
chsend(fs->admchan, a);
@@ -2396,8 +2396,8 @@
bp = unpackbp(kv.v, kv.nv);
freetree(bp, pred);
qlock(&fs->mutlk);
- epochclean();
qunlock(&fs->mutlk);
+ epochclean();
}
}
if(rb.gen > pred)
@@ -2432,8 +2432,8 @@
if(bp.gen > t->pred)
freebp(nil, bp);
qlock(&fs->mutlk);
- epochclean();
qunlock(&fs->mutlk);
+ epochclean();
}
btexit(&s);
freetree(t->bp, t->pred);
@@ -2445,12 +2445,12 @@
char buf[Kvmax];
Msg mb[Kvmax/Offksz];
Bptr bp, nb, *oldhd;
+ int i, nm;
vlong off;
Tree *t;
Arena *a;
Amsg *am;
Blk *b;
- int i, nm;
if((oldhd = calloc(fs->narena, sizeof(Bptr))) == nil)
sysfatal("malloc log heads");
@@ -2471,31 +2471,31 @@
if(am->halt)
ainc(&fs->rdonly);
- qlock(&fs->mutlk);
for(i = 0; i < fs->narena; i++){
a = &fs->arenas[i];
+ oldhd[i].addr = -1;
+ oldhd[i].hash = -1;
+ oldhd[i].gen = -1;
qlock(a);
- if(a->nlog < a->reserve/(10*Blksz)){
- oldhd[i].addr = -1;
- oldhd[i].hash = -1;
- oldhd[i].gen = -1;
- qunlock(a);
- continue;
+ /*
+ * arbitrary heuristic -- 10% of our reserved
+ * space seems like a fine time to compress.
+ */
+ if(a->nlog >= a->reserve/(10*Blksz)){
+ oldhd[i] = a->loghd;
+ epochstart(id);
+ if(waserror()){
+ epochend(id);
+ qunlock(a);
+ nexterror();
+ }
+ compresslog(a);
+ epochend(id);
+ poperror();
}
- if(waserror()){
- qunlock(&fs->mutlk);
- qunlock(a);
- nexterror();
- }
- oldhd[i] = a->loghd;
- epochstart(id);
- compresslog(a);
qunlock(a);
- epochend(id);
epochclean();
- poperror();
}
- qunlock(&fs->mutlk);
sync();
for(i = 0; i < fs->narena; i++){
@@ -2507,8 +2507,8 @@
freeblk(nil, b);
dropblk(b);
epochend(id);
- epochclean();
qunlock(&fs->mutlk);
+ epochclean();
}
}
@@ -2611,8 +2611,8 @@
epochstart(id);
upsert(am->mnt, mb, nm);
epochend(id);
- epochclean();
qunlock(&fs->mutlk);
+ epochclean();
poperror();
nm = 0;
}