ref: 383a92cb9963a04aea7b0c31048a7bb1eabb9476
parent: a742b7cb40538d0bdd5d4420a3478f7c7d60f157
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Jul 19 01:24:29 EDT 2022
quiesce: fix race if the writer deferred frees between the quiesce and grabbing/trimming the freelist, we could free blocks from the next epoch, which would be bad.
--- a/blk.c
+++ b/blk.c
@@ -902,22 +902,21 @@
if(fs->active[i] == fs->lastactive[i])
allquiesced = 0;
}
- if(allquiesced)
+ p = nil;
+ if(allquiesced){
+ inc64(&fs->qgen, 1);
for(i = 0; i < fs->nquiesce; i++)
fs->lastactive[i] = fs->active[i];
- unlock(&fs->activelk);
- if(!allquiesced)
- return;
- inc64(&fs->qgen, 1);
- lock(&fs->freelk);
- p = nil;
- if(fs->freep != nil){
- p = fs->freep->next;
- fs->freep->next = nil;
+ lock(&fs->freelk);
+ if(fs->freep != nil){
+ p = fs->freep->next;
+ fs->freep->next = nil;
+ }
+ fs->freep = fs->freehd;
+ unlock(&fs->freelk);
}
- fs->freep = fs->freehd;
- unlock(&fs->freelk);
+ unlock(&fs->activelk);
while(p != nil){
n = p->next;