shithub: gefs

Download patch

ref: 24f1cad509991cf7ef87830ac5e73f81593fc6e5
parent: b017ff28be91c9f3aca6e25f0588903efce5fefd
author: Ori Bernstein <ori@eigenstate.org>
date: Fri May 3 22:37:43 EDT 2024

snap: free deadlist blocks directly

unbounded amounts of deferred reclamation are bad,
but because of the way that these trees are deadlisted,
all the blocks are already guaranteed to be unreachable,
so we don't need to defer the reclamation at all.

--- a/snap.c
+++ b/snap.c
@@ -151,7 +151,9 @@
 freedl(Dlist *dl, int docontents)
 {
 	char buf[Kvmax];
-	Bptr bp, fb;
+	Arena *a;
+	Qent qe;
+	Bptr bp;
 	Msg m;
 	Blk *b;
 	char *p;
@@ -164,19 +166,33 @@
 	}
 	while(bp.addr != -1){
 		b = getblk(bp, 0);
+		/*
+		 * Because these deadlists are dead-dead at this point,
+		 * they'll never be read from again; we can avoid worrying
+		 * about deferred reclamation, and queue them up to be freed
+		 * directly, which means we don't need to worry about watiing
+		 * for a quiescent state, and the associated out-of-block
+		 * deadlocks that come with it.
+		 */
 		if(docontents){
 			for(p = b->data; p != b->data+b->logsz; p += 8){
-				fb.addr = UNPACK64(p);
-				fb.hash = -1;
-				fb.gen = -1;
-				traceb("dlclear", fb);
-				freeblk(nil, nil, fb);
+				qe.op = Qfree;
+				qe.bp.addr = UNPACK64(p);
+				qe.bp.hash = -1;
+				qe.bp.gen = -1;
+				qe.b = nil;
+				a = getarena(qe.bp.addr);
+				qput(a->sync, qe);
+				traceb("dlclear", qe.bp);
 			}
 		}
 		bp = b->logp;
-		traceb("dlfreeb", b->bp);
-		freeblk(nil, b, b->bp);
-		dropblk(b);
+		qe.op = Qfree;
+		qe.bp = b->bp;
+		qe.b = b;
+		a = getarena(qe.bp.addr);
+		qput(a->sync, qe);
+		traceb("dlfreeb", qe.bp);
 	}
 }