shithub: riscv

Download patch

ref: 6f9838a6a5b80e0253bdc8fb194ad6f15eb655f5
parent: 6e64d30454f71ecda88dba1bd792e97509115d73
author: cinap_lenrek <[email protected]>
date: Sun Jan 16 14:25:11 EST 2022

kernel: make Page.txtflush into an array

To avoid a MAXMACH limit of 32 and make
txtflush into an array for the bitmap.

Provide portable macros for testing and clearing
the bits: needtxtflush(), donetxtflush().

On pc/pc64, define inittxtflush()/settxtflush()
as no-op macros, avoiding the storage overhead of
the txtflush array alltogether.

--- a/sys/src/9/bcm/mmu.c
+++ b/sys/src/9/bcm/mmu.c
@@ -254,11 +254,10 @@
 	/* clear out the current entry */
 	mmuinvalidateaddr(PPN(va));
 
-	if((page->txtflush & (1<<m->machno)) != 0){
-		/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
+	if(needtxtflush(page)){
 		cachedwbse((void*)(page->pa|KZERO), BY2PG);
 		cacheiinvse((void*)page->va, BY2PG);
-		page->txtflush &= ~(1<<m->machno);
+		donetxtflush(page);
 	}
 	//checkmmu(va, PPN(pa));
 	splx(s);
--- a/sys/src/9/bcm64/mmu.c
+++ b/sys/src/9/bcm64/mmu.c
@@ -460,11 +460,10 @@
 		flushasidva((uvlong)up->asid<<48 | va>>12);
 	*pte = pa | PTEPAGE | PTEUSER | PTEPXN | PTENG | PTEAF |
 		(((pa & PTEMA(7)) == PTECACHED)? PTESH(SHARE_INNER): PTESH(SHARE_OUTER));
-	if(pg->txtflush & (1UL<<m->machno)){
-		/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
+	if(needtxtflush(pg)){
 		cachedwbinvse(kmap(pg), BY2PG);
 		cacheiinvse((void*)va, BY2PG);
-		pg->txtflush &= ~(1UL<<m->machno);
+		donetxtflush(pg);
 	}
 	splx(s);
 }
--- a/sys/src/9/cycv/mmu.c
+++ b/sys/src/9/cycv/mmu.c
@@ -168,14 +168,14 @@
 	old = *e;
 	*e = pa | L2VALID | L2USER | L2LOCAL;
 	tmpunmap(l2);
-	splx(s);
 	if((old & L2VALID) != 0)
 		flushpg((void *) va);
-	if(pg->txtflush & (1<<m->machno)){
+	if(needtxtflush(pg)){
 		cleandse((void *) va, (void *) (va + BY2PG));
 		invalise((void *) va, (void *) (va + BY2PG));
-		pg->txtflush &= ~(1<<m->machno);
+		donetxtflush(pg);
 	}
+	splx(s);
 }
 
 void
--- a/sys/src/9/kw/mmu.c
+++ b/sys/src/9/kw/mmu.c
@@ -345,9 +345,9 @@
 	 *  rather than direct mapped.
 	 */
 	cachedwbinv();
-	if(page->txtflush){
+	if(needtxtflush(page)){
 		cacheiinv();
-		page->txtflush = 0;
+		donetxtflush(page);
 	}
 	//print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
 }
--- a/sys/src/9/mtx/mmu.c
+++ b/sys/src/9/mtx/mmu.c
@@ -218,10 +218,10 @@
 	q[1] = pa;
 	sync();
 
-	if(pg->txtflush & (1<<m->machno)){
+	if(needtxtflush(pg)){
 		dcflush((void*)pg->va, BY2PG);
 		icflush((void*)pg->va, BY2PG);
-		pg->txtflush &= ~(1<<m->machno);
+		donetxtflush(pg);
 	}
 }
 
--- a/sys/src/9/omap/mmu.c
+++ b/sys/src/9/omap/mmu.c
@@ -322,9 +322,9 @@
 	 *  rather than direct mapped.
 	 */
 	cachedwbinv();
-	if(page->txtflush){
+	if(needtxtflush(page)){
 		cacheiinv();
-		page->txtflush = 0;
+		donetxtflush(page);
 	}
 	//print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
 }
--- a/sys/src/9/pc/dat.h
+++ b/sys/src/9/pc/dat.h
@@ -159,6 +159,9 @@
 	void	*vmx;
 };
 
+#define	inittxtflush(p)
+#define	settxtflush(p,c)
+
 #include "../port/portdat.h"
 
 typedef struct {
--- a/sys/src/9/pc/mem.h
+++ b/sys/src/9/pc/mem.h
@@ -21,11 +21,6 @@
 #define	BLOCKALIGN	8
 #define	FPalign		16
 
-/*
- * In 32-bit mode, the MAXMACH limit is 32 without
- * changing the way active.machs is defined and used
- * (unfortunately, it is also used in the port code).
- */
 #define	MAXMACH		32			/* max # cpus system can run */
 #define	KSTACK		4096			/* Size of kernel stack */
 
--- a/sys/src/9/pc64/dat.h
+++ b/sys/src/9/pc64/dat.h
@@ -169,6 +169,9 @@
 	void	*vmx;
 };
 
+#define	inittxtflush(p)
+#define	settxtflush(p,c)
+
 #include "../port/portdat.h"
 
 typedef struct {
--- a/sys/src/9/port/devsegment.c
+++ b/sys/src/9/port/devsegment.c
@@ -523,7 +523,7 @@
 			p->ref = 1;
 			p->va = va;
 			p->modref = 0;
-			p->txtflush = ~0;
+			settxtflush(p, 1);
 			
 			k = kmap(p);
 			memset((void*)VA(k), 0, BY2PG);
--- a/sys/src/9/port/fault.c
+++ b/sys/src/9/port/fault.c
@@ -135,8 +135,7 @@
 	}
 done:
 	putpage(new);
-	if(s->flushme)
-		(*p)->txtflush = ~0;
+	settxtflush(*p, s->flushme);
 }
 
 static int
@@ -202,8 +201,7 @@
 			new = newpage(0, &s, addr);
 			if(s == nil)
 				return -1;
-			if(s->flushme)
-				new->txtflush = ~0;
+			settxtflush(new, s->flushme);
 			*pg = new;
 			copypage(old, *pg);
 			putpage(old);
@@ -242,8 +240,7 @@
 	pg.ref = 1;
 	pg.va = addr;
 	pg.pa = s->pseg->pa+(addr-s->base);
-	if(s->flushme)
-		pg.txtflush = ~0;
+	settxtflush(&pg, s->flushme);
 
 	mmuphys = PPN(pg.pa) | PTEVALID;
 	if((attr & SG_RONLY) == 0)
--- a/sys/src/9/port/page.c
+++ b/sys/src/9/port/page.c
@@ -227,7 +227,7 @@
 	p->ref = 1;
 	p->va = va;
 	p->modref = 0;
-	p->txtflush = 0;
+	inittxtflush(p);
 
 	if(clear) {
 		k = kmap(p);
@@ -344,7 +344,6 @@
 		putpage(p);
 	}
 }
-
 
 Pte*
 ptecpy(Pte *old)
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -329,10 +329,19 @@
 	uintptr	va;			/* Virtual address for user */
 	uintptr	daddr;			/* Disc address on swap */
 	Image	*image;			/* Associated text or swap image */
-	ulong	txtflush;		/* Flush icache for putmmu */
 	ushort	refage;			/* Swap reference age */
 	char	modref;			/* Simulated modify/reference bits */
 	char	color;			/* Cache coloring */
+
+#ifndef inittxtflush
+	/* Flush icache bitmap for putmmu() */
+	ulong	txtflush[(MAXMACH+31)/32];
+
+#define inittxtflush(p)	memset((p)->txtflush, 0, sizeof((p)->txtflush))
+#define settxtflush(p, c) if(c) memset((p)->txtflush, ~0, sizeof((p)->txtflush))
+#define needtxtflush(p)	((p)->txtflush[m->machno>>5] & (1 << (m->machno&0x1F)))
+#define donetxtflush(p)	((p)->txtflush[m->machno>>5] &= ~(1 << (m->machno&0x1F)))
+#endif
 };
 
 struct Swapalloc
--- a/sys/src/9/port/segment.c
+++ b/sys/src/9/port/segment.c
@@ -718,8 +718,7 @@
 				pg = &pte->pages[off/BY2PG];
 				pe = pg + len/BY2PG;
 				while(pg < pe) {
-					if(!pagedout(*pg))
-						(*pg)->txtflush = ~0;
+					settxtflush(*pg, !pagedout(*pg));
 					pg++;
 				}
 			}
--- a/sys/src/9/port/userinit.c
+++ b/sys/src/9/port/userinit.c
@@ -52,7 +52,7 @@
 	k = kmap(p);
 	memmove((void*)VA(k), initcode, sizeof(initcode));
 	kunmap(k);
-	p->txtflush = ~0;
+	settxtflush(p, 1);
 	segpage(up->seg[TSEG], p);
 	up->seg[TSEG]->flushme = 1;
 
--- a/sys/src/9/ppc/mmu.c
+++ b/sys/src/9/ppc/mmu.c
@@ -245,10 +245,10 @@
 	q[0] = ptehi;
 	q[1] = pa;
 
-	if(pg->txtflush & (1<<m->machno)){
+	if(needtxtflush(pg)){
 		dcflush((void*)pg->va, BY2PG);
 		icflush((void*)pg->va, BY2PG);
-		pg->txtflush &= ~(1<<m->machno);
+		donetxtflush(pg);
 	}
 }
 
--- a/sys/src/9/sgi/mmu.c
+++ b/sys/src/9/sgi/mmu.c
@@ -389,9 +389,9 @@
 	x = gettlbp(tlbvirt, tlbent);
 	if(x < 0) x = getrandom();
 	puttlbx(x, entry->virt, entry->phys0, entry->phys1, PGSZ);
-	if(pg->txtflush & (1<<m->machno)){
+	if(needtxtflush(pg)){
 		icflush((void*)pg->va, BY2PG);
-		pg->txtflush &= ~(1<<m->machno);
+		donetxtflush(pg);
 	}
 	splx(s);
 }
--- a/sys/src/9/teg2/mmu.c
+++ b/sys/src/9/teg2/mmu.c
@@ -574,10 +574,11 @@
 	 */
 	l1cache->wb();
 
-	if(page->txtflush & (1<<m->machno)){
+	if(needtxtflush(page)){
 		cacheiinv();
-		page->txtflush &= ~(1<<m->machno);
+		donetxtflush(page);
 	}
+
 	if (Debug)
 		iprint("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
 }
--- a/sys/src/9/zynq/mmu.c
+++ b/sys/src/9/zynq/mmu.c
@@ -176,14 +176,14 @@
 	old = *e;
 	*e = pa | L2VALID | L2USER | L2LOCAL;
 	tmpunmap(l2);
-	splx(s);
 	if((old & L2VALID) != 0)
 		flushpg((void *) va);
-	if(pg->txtflush & (1<<m->machno)){
+	if(needtxtflush(pg)){
 		cleandse((void *) va, (void *) (va + BY2PG));
 		invalise((void *) va, (void *) (va + BY2PG));
-		pg->txtflush &= ~(1<<m->machno);
+		donetxtflush(pg);
 	}
+	splx(s);
 }
 
 void