changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: kernel: reduce Page structure size by changing Page.cachectl[]

changeset 4250: d819f0505c21
parent 4249: 6f1d737cc866
child 4251: a5a45bb148ad
author: cinap_lenrek@felloff.net
date: Sat, 07 Feb 2015 02:52:23 +0100
files: sys/src/9/alphapc/main.c sys/src/9/bcm/main.c sys/src/9/bcm/mmu.c sys/src/9/bitsy/main.c sys/src/9/bitsy/mmu.c sys/src/9/kw/main.c sys/src/9/kw/mmu.c sys/src/9/mtx/main.c sys/src/9/mtx/mmu.c sys/src/9/omap/main.c sys/src/9/omap/mmu.c sys/src/9/omap4/main.c sys/src/9/pc/main.c sys/src/9/pc64/main.c sys/src/9/port/devproc.c sys/src/9/port/fault.c sys/src/9/port/page.c sys/src/9/port/portdat.h sys/src/9/port/segment.c sys/src/9/ppc/main.c sys/src/9/ppc/mmu.c sys/src/9/teg2/main.c sys/src/9/teg2/mmu.c sys/src/9/xen/main.c sys/src/9/zynq/main.c sys/src/9/zynq/mmu.c
description: kernel: reduce Page structure size by changing Page.cachectl[]

there are no kernels currently that do page coloring,
so the only use of cachectl[] is flushing the icache
(on arm and ppc).

on pc64, cachectl consumes 32 bytes in each page resulting
in over 200 megabytes of overhead for 32gb of ram with 4K
pages.

this change removes cachectl[] and adds txtflush ulong
that is set to ~0 by pio() to instruct putmmu() to flush
the icache.
     1.1--- a/sys/src/9/alphapc/main.c
     1.2+++ b/sys/src/9/alphapc/main.c
     1.3@@ -255,7 +255,7 @@ userinit(void)
     1.4 	s->flushme++;
     1.5 	p->seg[TSEG] = s;
     1.6 	pg = newpage(1, 0, UTZERO);
     1.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
     1.8+	pg->txtflush = ~0;
     1.9 	segpage(s, pg);
    1.10 	k = kmap(s->map[0]->pages[0]);
    1.11 	memmove((uchar*)VA(k), initcode, sizeof initcode);
     2.1--- a/sys/src/9/bcm/main.c
     2.2+++ b/sys/src/9/bcm/main.c
     2.3@@ -413,7 +413,7 @@ userinit(void)
     2.4 	s = newseg(SG_TEXT, UTZERO, 1);
     2.5 	p->seg[TSEG] = s;
     2.6 	pg = newpage(1, 0, UTZERO);
     2.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
     2.8+	pg->txtflush = ~0;
     2.9 	segpage(s, pg);
    2.10 	k = kmap(s->map[0]->pages[0]);
    2.11 	memmove(UINT2PTR(VA(k)), initcode, sizeof initcode);
     3.1--- a/sys/src/9/bcm/mmu.c
     3.2+++ b/sys/src/9/bcm/mmu.c
     3.3@@ -265,10 +265,9 @@ putmmu(uintptr va, uintptr pa, Page* pag
     3.4 	 *  rather than direct mapped.
     3.5 	 */
     3.6 	cachedwbinv();
     3.7-	if(page->cachectl[0] == PG_TXTFLUSH){
     3.8-		/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
     3.9+	if(page->txtflush){
    3.10 		cacheiinv();
    3.11-		page->cachectl[0] = PG_NOFLUSH;
    3.12+		page->txtflush = 0;
    3.13 	}
    3.14 	checkmmu(va, PPN(pa));
    3.15 }
     4.1--- a/sys/src/9/bitsy/main.c
     4.2+++ b/sys/src/9/bitsy/main.c
     4.3@@ -225,7 +225,7 @@ userinit(void)
     4.4 	s = newseg(SG_TEXT, UTZERO, 1);
     4.5 	p->seg[TSEG] = s;
     4.6 	pg = newpage(1, 0, UTZERO);
     4.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
     4.8+	pg->txtflush = ~0;
     4.9 	segpage(s, pg);
    4.10 	k = kmap(s->map[0]->pages[0]);
    4.11 	memmove((ulong*)VA(k), initcode, sizeof initcode);
     5.1--- a/sys/src/9/bitsy/mmu.c
     5.2+++ b/sys/src/9/bitsy/mmu.c
     5.3@@ -406,10 +406,9 @@ putmmu(uintptr va, uintptr pa, Page *pg)
     5.4 	 *  rather than direct mapped.
     5.5 	 */
     5.6 	cachewb();
     5.7-	if(pg->cachectl[0] == PG_TXTFLUSH){
     5.8-		/* pio() sets PG_TXTFLUSH whenever a text page has been written */
     5.9+	if(pg->txtflush){
    5.10 		icacheinvalidate();
    5.11-		pg->cachectl[0] = PG_NOFLUSH;
    5.12+		pg->txtflush = 0;
    5.13 	}
    5.14 
    5.15 	splx(s);
     6.1--- a/sys/src/9/kw/main.c
     6.2+++ b/sys/src/9/kw/main.c
     6.3@@ -587,7 +587,7 @@ userinit(void)
     6.4 	s->flushme++;
     6.5 	p->seg[TSEG] = s;
     6.6 	pg = newpage(1, 0, UTZERO);
     6.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
     6.8+	pg->txtflush = ~0;
     6.9 	segpage(s, pg);
    6.10 	k = kmap(s->map[0]->pages[0]);
    6.11 	memmove(UINT2PTR(VA(k)), initcode, sizeof initcode);
     7.1--- a/sys/src/9/kw/mmu.c
     7.2+++ b/sys/src/9/kw/mmu.c
     7.3@@ -353,10 +353,9 @@ putmmu(uintptr va, uintptr pa, Page* pag
     7.4 	 *  rather than direct mapped.
     7.5 	 */
     7.6 	cachedwbinv();
     7.7-	if(page->cachectl[0] == PG_TXTFLUSH){
     7.8-		/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
     7.9+	if(page->txtflush){
    7.10 		cacheiinv();
    7.11-		page->cachectl[0] = PG_NOFLUSH;
    7.12+		page->txtflush = 0;
    7.13 	}
    7.14 	//print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
    7.15 }
     8.1--- a/sys/src/9/mtx/main.c
     8.2+++ b/sys/src/9/mtx/main.c
     8.3@@ -198,7 +198,7 @@ userinit(void)
     8.4 	s->flushme++;
     8.5 	p->seg[TSEG] = s;
     8.6 	pg = newpage(1, 0, UTZERO);
     8.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
     8.8+	pg->txtflush = ~0;
     8.9 	segpage(s, pg);
    8.10 	k = kmap(s->map[0]->pages[0]);
    8.11 	memmove((ulong*)VA(k), initcode, sizeof initcode);
     9.1--- a/sys/src/9/mtx/mmu.c
     9.2+++ b/sys/src/9/mtx/mmu.c
     9.3@@ -179,7 +179,6 @@ void
     9.4 putmmu(uintptr va, uintptr pa, Page *pg)
     9.5 {
     9.6 	int mp;
     9.7-	char *ctl;
     9.8 	ulong *p, *ep, *q, pteg;
     9.9 	ulong vsid, ptehi, x, hash;
    9.10 
    9.11@@ -218,19 +217,10 @@ putmmu(uintptr va, uintptr pa, Page *pg)
    9.12 	q[1] = pa;
    9.13 	sync();
    9.14 
    9.15-	ctl = &pg->cachectl[m->machno];
    9.16-	switch(*ctl) {
    9.17-	case PG_NEWCOL:
    9.18-	default:
    9.19-		panic("putmmu: %d\n", *ctl);
    9.20-		break;
    9.21-	case PG_NOFLUSH:
    9.22-		break;
    9.23-	case PG_TXTFLUSH:
    9.24+	if(pg->txtflush & (1<<m->machno)){
    9.25 		dcflush((void*)pg->va, BY2PG);
    9.26 		icflush((void*)pg->va, BY2PG);
    9.27-		*ctl = PG_NOFLUSH;
    9.28-		break;
    9.29+		pg->txtflush &= ~(1<<m->machno);
    9.30 	}
    9.31 }
    9.32 
    10.1--- a/sys/src/9/omap/main.c
    10.2+++ b/sys/src/9/omap/main.c
    10.3@@ -565,7 +565,7 @@ userinit(void)
    10.4 	s = newseg(SG_TEXT, UTZERO, 1);
    10.5 	p->seg[TSEG] = s;
    10.6 	pg = newpage(1, 0, UTZERO);
    10.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
    10.8+	pg->txtflush = ~0;
    10.9 	segpage(s, pg);
   10.10 	k = kmap(s->map[0]->pages[0]);
   10.11 	memmove(UINT2PTR(VA(k)), initcode, sizeof initcode);
    11.1--- a/sys/src/9/omap/mmu.c
    11.2+++ b/sys/src/9/omap/mmu.c
    11.3@@ -330,10 +330,9 @@ putmmu(uintptr va, uintptr pa, Page* pag
    11.4 	 *  rather than direct mapped.
    11.5 	 */
    11.6 	cachedwbinv();
    11.7-	if(page->cachectl[0] == PG_TXTFLUSH){
    11.8-		/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
    11.9+	if(page->txtflush){
   11.10 		cacheiinv();
   11.11-		page->cachectl[0] = PG_NOFLUSH;
   11.12+		page->txtflush = 0;
   11.13 	}
   11.14 	//print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
   11.15 }
    12.1--- a/sys/src/9/omap4/main.c
    12.2+++ b/sys/src/9/omap4/main.c
    12.3@@ -134,7 +134,7 @@ userinit(void)
    12.4 	s->flushme++;
    12.5 	p->seg[TSEG] = s;
    12.6 	pg = newpage(0, 0, UTZERO);
    12.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
    12.8+	pg->txtflush = ~0;
    12.9 	segpage(s, pg);
   12.10 	v = vmap(pg->pa, BY2PG);
   12.11 	memset(v, 0, BY2PG);
    13.1--- a/sys/src/9/pc/main.c
    13.2+++ b/sys/src/9/pc/main.c
    13.3@@ -307,7 +307,7 @@ userinit(void)
    13.4 	s->flushme++;
    13.5 	p->seg[TSEG] = s;
    13.6 	pg = newpage(0, 0, UTZERO);
    13.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
    13.8+	pg->txtflush = ~0;
    13.9 	segpage(s, pg);
   13.10 	v = tmpmap(pg);
   13.11 	memset(v, 0, BY2PG);
    14.1--- a/sys/src/9/pc64/main.c
    14.2+++ b/sys/src/9/pc64/main.c
    14.3@@ -461,7 +461,7 @@ userinit(void)
    14.4 	s->flushme++;
    14.5 	p->seg[TSEG] = s;
    14.6 	pg = newpage(0, 0, UTZERO);
    14.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
    14.8+	pg->txtflush = ~0;
    14.9 	segpage(s, pg);
   14.10 	v = kmap(pg);
   14.11 	memset(v, 0, BY2PG);
    15.1--- a/sys/src/9/port/devproc.c
    15.2+++ b/sys/src/9/port/devproc.c
    15.3@@ -1580,12 +1580,12 @@ procctlmemio(Proc *p, uintptr offset, in
    15.4 		memmove(b, a, n);
    15.5 	kunmap(k);
    15.6 
    15.7-	/* Ensure the process sees text page changes */
    15.8-	if(s->flushme)
    15.9-		memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
   15.10-
   15.11-	if(!read)
   15.12+	if(!read){
   15.13+		/* Ensure the process sees text page changes */
   15.14+		if(s->flushme)
   15.15+			pg->txtflush = ~0;
   15.16 		p->newtlb = 1;
   15.17+	}
   15.18 
   15.19 	qunlock(s);
   15.20 	poperror();
    16.1--- a/sys/src/9/port/fault.c
    16.2+++ b/sys/src/9/port/fault.c
    16.3@@ -187,7 +187,7 @@ retry:
    16.4 done:
    16.5 	putpage(new);
    16.6 	if(s->flushme)
    16.7-		memset((*p)->cachectl, PG_TXTFLUSH, sizeof((*p)->cachectl));
    16.8+		(*p)->txtflush = ~0;
    16.9 }
   16.10 
   16.11 void	(*checkaddr)(uintptr, Segment *, Page *);
   16.12@@ -263,6 +263,8 @@ fixfault(Segment *s, uintptr addr, int r
   16.13 			new = newpage(0, &s, addr);
   16.14 			if(s == nil)
   16.15 				return -1;
   16.16+			if(s->flushme)
   16.17+				new->txtflush = ~0;
   16.18 			*pg = new;
   16.19 			copypage(old, *pg);
   16.20 			putpage(old);
    17.1--- a/sys/src/9/port/page.c
    17.2+++ b/sys/src/9/port/page.c
    17.3@@ -145,8 +145,7 @@ newpage(int clear, Segment **s, uintptr 
    17.4 {
    17.5 	Page *p, **l;
    17.6 	KMap *k;
    17.7-	uchar ct;
    17.8-	int i, color;
    17.9+	int color;
   17.10 
   17.11 	color = getpgcolor(va);
   17.12 	lock(&palloc);
   17.13@@ -195,12 +194,9 @@ newpage(int clear, Segment **s, uintptr 
   17.14 		l = &p->next;
   17.15 	}
   17.16 
   17.17-	ct = PG_NOFLUSH;
   17.18 	if(p == nil) {
   17.19 		l = &palloc.head;
   17.20 		p = *l;
   17.21-		p->color = color;
   17.22-		ct = PG_NEWCOL;
   17.23 	}
   17.24 
   17.25 	*l = p->next;
   17.26@@ -211,8 +207,7 @@ newpage(int clear, Segment **s, uintptr 
   17.27 	p->ref = 1;
   17.28 	p->va = va;
   17.29 	p->modref = 0;
   17.30-	for(i = 0; i < MAXMACH; i++)
   17.31-		p->cachectl[i] = ct;
   17.32+	p->txtflush = 0;
   17.33 
   17.34 	if(clear) {
   17.35 		k = kmap(p);
    18.1--- a/sys/src/9/port/portdat.h
    18.2+++ b/sys/src/9/port/portdat.h
    18.3@@ -292,11 +292,6 @@ struct Note
    18.4 
    18.5 enum
    18.6 {
    18.7-	PG_NOFLUSH	= 0,
    18.8-	PG_TXTFLUSH	= 1,		/* flush dcache and invalidate icache */
    18.9-	PG_DATFLUSH	= 2,		/* flush both i & d caches (UNUSED) */
   18.10-	PG_NEWCOL	= 3,		/* page has been recolored */
   18.11-
   18.12 	PG_MOD		= 0x01,		/* software modified bit */
   18.13 	PG_REF		= 0x02,		/* software referenced bit */
   18.14 };
   18.15@@ -309,10 +304,10 @@ struct Page
   18.16 	uintptr	va;			/* Virtual address for user */
   18.17 	uintptr	daddr;			/* Disc address on swap */
   18.18 	Image	*image;			/* Associated text or swap image */
   18.19+	ulong	txtflush;		/* Flush icache for putmmu */
   18.20 	ushort	refage;			/* Swap reference age */
   18.21 	char	modref;			/* Simulated modify/reference bits */
   18.22 	char	color;			/* Cache coloring */
   18.23-	char	cachectl[MAXMACH];	/* Cache flushing control for putmmu */
   18.24 };
   18.25 
   18.26 struct Swapalloc
    19.1--- a/sys/src/9/port/segment.c
    19.2+++ b/sys/src/9/port/segment.c
    19.3@@ -669,7 +669,7 @@ pteflush(Pte *pte, int s, int e)
    19.4 	for(i = s; i < e; i++) {
    19.5 		pg = pte->pages[i];
    19.6 		if(!pagedout(pg))
    19.7-			memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
    19.8+			pg->txtflush = ~0;
    19.9 	}
   19.10 }
   19.11 
    20.1--- a/sys/src/9/ppc/main.c
    20.2+++ b/sys/src/9/ppc/main.c
    20.3@@ -233,7 +233,7 @@ userinit(void)
    20.4 	s->flushme++;
    20.5 	p->seg[TSEG] = s;
    20.6 	pg = newpage(1, 0, UTZERO);
    20.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
    20.8+	pg->txtflush = ~0;
    20.9 	segpage(s, pg);
   20.10 	k = kmap(s->map[0]->pages[0]);
   20.11 	memmove((ulong*)VA(k), initcode, sizeof initcode);
    21.1--- a/sys/src/9/ppc/mmu.c
    21.2+++ b/sys/src/9/ppc/mmu.c
    21.3@@ -199,7 +199,6 @@ void
    21.4 putmmu(uintptr va, uintptr pa, Page *pg)
    21.5 {
    21.6 	int mp;
    21.7-	char *ctl;
    21.8 	ulong *p, *ep, *q, pteg;
    21.9 	ulong vsid, hash;
   21.10 	ulong ptehi, x;
   21.11@@ -244,21 +243,11 @@ putmmu(uintptr va, uintptr pa, Page *pg)
   21.12 	q[0] = ptehi;
   21.13 	q[1] = pa;
   21.14 
   21.15-	ctl = &pg->cachectl[m->machno];
   21.16-	switch(*ctl) {
   21.17-	case PG_NEWCOL:
   21.18-	default:
   21.19-		panic("putmmu: %d\n", *ctl);
   21.20-		break;
   21.21-	case PG_TXTFLUSH:
   21.22+	if(pg->txtflush & (1<<m->machno)){
   21.23 		dcflush((void*)pg->va, BY2PG);
   21.24 		icflush((void*)pg->va, BY2PG);
   21.25-		*ctl = PG_NOFLUSH;
   21.26-		break;
   21.27-	case PG_NOFLUSH:
   21.28-		break;
   21.29+		pg->txtflush &= ~(1<<m->machno);
   21.30 	}
   21.31-
   21.32 }
   21.33 
   21.34 void
    22.1--- a/sys/src/9/teg2/main.c
    22.2+++ b/sys/src/9/teg2/main.c
    22.3@@ -792,7 +792,7 @@ userinit(void)
    22.4 	s = newseg(SG_TEXT, UTZERO, 1);
    22.5 	p->seg[TSEG] = s;
    22.6 	pg = newpage(1, 0, UTZERO);
    22.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
    22.8+	pg->txtflush = ~0;
    22.9 	segpage(s, pg);
   22.10 	k = kmap(s->map[0]->pages[0]);
   22.11 	memmove(UINT2PTR(VA(k)), initcode, sizeof initcode);
    23.1--- a/sys/src/9/teg2/mmu.c
    23.2+++ b/sys/src/9/teg2/mmu.c
    23.3@@ -582,10 +582,9 @@ putmmu(uintptr va, uintptr pa, Page* pag
    23.4 	 */
    23.5 	l1cache->wb();
    23.6 
    23.7-	if(page->cachectl[0] == PG_TXTFLUSH){
    23.8-		/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
    23.9+	if(page->txtflush & (1<<m->machno)){
   23.10 		cacheiinv();
   23.11-		page->cachectl[0] = PG_NOFLUSH;
   23.12+		page->txtflush &= ~(1<<m->machno);
   23.13 	}
   23.14 	if (Debug)
   23.15 		iprint("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
    24.1--- a/sys/src/9/xen/main.c
    24.2+++ b/sys/src/9/xen/main.c
    24.3@@ -245,7 +245,7 @@ userinit(void)
    24.4 	s->flushme++;
    24.5 	p->seg[TSEG] = s;
    24.6 	pg = newpage(1, 0, UTZERO);
    24.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
    24.8+	pg->txtflush = ~0;
    24.9 	segpage(s, pg);
   24.10 	k = kmap(s->map[0]->pages[0]);
   24.11 	memmove((ulong*)VA(k), initcode, sizeof initcode);
    25.1--- a/sys/src/9/zynq/main.c
    25.2+++ b/sys/src/9/zynq/main.c
    25.3@@ -306,7 +306,7 @@ userinit(void)
    25.4 	s->flushme++;
    25.5 	p->seg[TSEG] = s;
    25.6 	pg = newpage(0, 0, UTZERO);
    25.7-	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
    25.8+	pg->txtflush = ~0;
    25.9 
   25.10 	segpage(s, pg);
   25.11 	v = tmpmap(pg->pa);
    26.1--- a/sys/src/9/zynq/mmu.c
    26.2+++ b/sys/src/9/zynq/mmu.c
    26.3@@ -140,7 +140,6 @@ putmmu(uintptr va, uintptr pa, Page *pg)
    26.4 	ulong *e;
    26.5 	ulong *l2;
    26.6 	PTE old;
    26.7-	char *ctl;
    26.8 	uintptr l2p;
    26.9 	int s;
   26.10 
   26.11@@ -180,11 +179,10 @@ putmmu(uintptr va, uintptr pa, Page *pg)
   26.12 	splx(s);
   26.13 	if((old & L2VALID) != 0)
   26.14 		flushpg((void *) va);
   26.15-	ctl = &pg->cachectl[m->machno];
   26.16-	if(*ctl == PG_TXTFLUSH){
   26.17+	if(pg->txtflush & (1<<m->machno)){
   26.18 		cleandse((void *) va, (void *) (va + BY2PG));
   26.19 		invalise((void *) va, (void *) (va + BY2PG));
   26.20-		*ctl = PG_NOFLUSH;
   26.21+		pg->txtflush &= ~(1<<m->machno);
   26.22 	}
   26.23 }
   26.24