code: mafs

Download patch

ref: 807264bdf7762d6450fd820a1815d90e1ccf357d
parent: c41caa3b068fca0e58bed789548f75c7222e8f46
author: 9ferno <gophone2015@gmail.com>
date: Wed Oct 26 00:03:59 EDT 2022

streamlined memory allocation global variables

--- a/all.h
+++ b/all.h
@@ -15,7 +15,6 @@
 	/*
 	https://cs.stackexchange.com/questions/11029/why-is-it-best-to-use-a-prime-number-as-a-mod-in-a-hashing-function
 		using small numbers for testing
-		using Nbuckets=2 for testing.
 
 	Size of buffer cache is approximately (Nbuckets * Ncollisions * Rawblocksize).
 
@@ -23,10 +22,7 @@
 	Ncollisions as the hash index lookup is faster than searching
 	through a linked list.
 	 */
-	Nbuckets = 256*KiB,	/* number of Hiob, hash buckets */
-	Ncollisions = 4,	/* soft limit after which we start reusing older Iobuf's */
-	Npendingwrites	= MiB,	/* write throttling */
-	Nmemunits = 8*MiB,	/* total memunit usage */
+	Ncollisions = 3,	/* soft limit after which we start reusing older Iobuf's */
 };
 
 typedef	struct	Hiob	Hiob;
@@ -84,7 +80,7 @@
 	u8 tofree;		/* free this Iobuf after the dirty blocks are written to the disk */
 };
 
-extern	u32	nbuckets;		/* n hash buckets for i/o */
+extern	u64	nbuckets;		/* n hash buckets for i/o */
 extern	Extents frees;		/* extents of free blocks on the disk */
 
 #include "fns.h"
@@ -113,7 +109,7 @@
 void	freeblockbuf(Iobuf *buf);
 void	freeblock(u64 blkno, u16 tag, u64 qpath);
 void	fsok(int ok);
-void	init(int doream);
+void	init(int doream, u64 size);
 u64		newqpath();
 u64		nperiblock(u16 tag);
 void	ream(u64 size);
--- a/free.c
+++ b/free.c
@@ -50,6 +50,7 @@
 		print("%s %llud bytes %llud blocks\n", devfile, size, size/Rawblocksize);
 
 	checkblock(Bdfrees, Tdentry, Qpfrees);
+	initextents(&frees);
 	getfrees(Bdfrees);
 // showextents("after getfrees", &frees);
 	showblocknos(1, &frees);
--- a/iobuf.c
+++ b/iobuf.c
@@ -1,6 +1,6 @@
 #include "all.h"
 
-u32  nbuckets = 0;	/* nbuckets derived from -m or Nbuckets */
+u64  nbuckets = 0;	/* number of hash buckets, -m changes it */
 Hiob *hiob = nil;	/* array of nbuckets */
 Extents frees = {0};/* extents of free blocks on the disk */
 
@@ -17,6 +17,10 @@
 {
 	memunitpool = sbrk(nunits * Rawblocksize);
 	initextents(&memunits);
+	if(chatty9p > 4)
+		dprint("initmemunitpool: memunitpool %p nunits*Rawblocksize %p\n",
+				memunitpool, nunits*Rawblocksize);
+	bfree(&memunits, (u64)memunitpool, nunits*Rawblocksize);
 }
 
 u8 *
@@ -24,11 +28,14 @@
 {
 	u64 m;
 
-	m = balloc(&memunits, 1);
+	m = balloc(&memunits, Rawblocksize);
 	if(m == 0)
 		panic("allocmemunit: no memory available");
 
-	return memunitpool+m;
+	if(chatty9p > 4)
+		dprint("allocmemunit: memunitpool %p m %p\n",
+				memunitpool, m);
+	return (u8*)m;
 }
 
 void
@@ -36,7 +43,7 @@
 {
 	if(m == 0)
 		panic("freememunit: m == 0\n");
-	bfree(&memunits, m-memunitpool, 1);
+	bfree(&memunits, (u64)m, Rawblocksize);
 }
 
 
@@ -88,7 +95,7 @@
 {
 	Hiob *hp;
 	Iobuf *s, *p;
-	s8 ncollisions;
+	u64 ncollisions;
 
 	hp = &hiob[blkno%nbuckets];
 
--- a/mafs.c
+++ b/mafs.c
@@ -44,7 +44,7 @@
 	int doream, stdio, netc;
 	char buf[Namelen];
 	int pid, ctl;
-	u64 nmemunits;
+	u64 nmemunits, size;
 
 	progname = "mafs";
 	procname = "init";
@@ -56,9 +56,9 @@
 	 */
 	rfork(RFNAMEG|RFNOTEG|RFREND);
 
-	nbuckets = Nbuckets;
-	npendingwrites = Npendingwrites;
-	nmemunits = Nmemunits;
+	nbuckets = 0;
+	npendingwrites = 0;
+	nmemunits = 0;
 	sfd = -1;
 	doream = stdio = netc = 0;
 
@@ -98,22 +98,37 @@
 	if(devfile == nil)
 		sysfatal("no disk file");
 
+	if (access(devfile, AREAD|AWRITE) == -1)
+		sysfatal("%s cannot access device", devfile);
+
+	size = devinit(devfile);
+	if(size == 0)
+		panic("null size %s", devfile);
+
+	/* 2/3rds of the memory for the pending writes
+		and 1/3rd for the buffer cache */
+	if(nmemunits == 0)
+		nmemunits = size/Rawblocksize > 8*MiB ? 8*MiB : size/Rawblocksize;
+	if(nmemunits < KiB)
+		nmemunits = KiB;
+	if(npendingwrites == 0)
+		npendingwrites = 2*nmemunits/3;
+	if(nbuckets == 0)
+		nbuckets = nmemunits/(3*Ncollisions);
+
 	if(chatty9p){
 		dprint("\nPlan 9 %d-bit file server with %d-deep indirect blocks\n",
 			sizeof(u64)*8, Niblock);
 		printsizes();
+		dprint("nmemunits %llud npendingwrites %llud nbuckets %llud\n",
+				nmemunits, npendingwrites, nbuckets);
 	}
 
-	if (access(devfile, AREAD|AWRITE) == -1)
-		sysfatal("%s cannot access device", devfile);
-
-	if(npendingwrites == 0)
-		npendingwrites = KiB;
-
 	formatinit();
 
 	initmemunitpool(nmemunits);
 	initextents(&frees);
+
 	tlocks = emalloc9p(NTLOCK * sizeof *tlocks);
 	initwriter();
 	iobufinit();
@@ -122,7 +137,7 @@
 	 * init the file system, ream it if needed, and get the block sizes.
 	 * service = config.service, if service is nil.
 	 */
-	init(doream);
+	init(doream, size);
 	if(service[0] == '\0')
 		snprint(service, Namelen, "%s", config.service);
 
--- a/reconcile.c
+++ b/reconcile.c
@@ -156,6 +156,7 @@
 	if(debug)
 		print("collect %s ", s->name);
 	s->es = emalloc(sizeof(Extents));
+	initextents(s->es);
 	while((s->buf = Brdstr(&s->bp, '\n', 1)) != nil) {
 		bno = atoll(s->buf);
 		add(s->es, bno, 1);
--- a/sub.c
+++ b/sub.c
@@ -480,17 +480,12 @@
 }
 
 void
-init(int doream)
+init(int doream, u64 size)
 {
 	u32 rbufsize;
-	u64 size;
 	Iobuf *sb, *b;
 	Superb *s;
 	s8 *rptr;
-
-	size = devinit(devfile);
-	if(size == 0)
-		panic("null size %s", devfile);
 
 	if(doream)
 		ream(size);
--- a/writer.c
+++ b/writer.c
@@ -119,7 +119,7 @@
 	w = emalloc9p(sizeof(Wbuf));
 	w->blkno = b->blkno;
 	w->payload = allocmemunit();
-	memcpy(w->io, b->io, Rawblocksize);
+	memcpy(w->payload, b->xiobuf, Rawblocksize);
 	if(drts.head == nil){
 		drts.head = drts.tail = w;
 	}else{