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.
This commit is contained in:
cinap_lenrek 2015-02-07 02:52:23 +01:00
parent f215b660b3
commit b8cf3cb879
26 changed files with 41 additions and 77 deletions

View file

@ -255,7 +255,7 @@ userinit(void)
s->flushme++; s->flushme++;
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO); pg = newpage(1, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
k = kmap(s->map[0]->pages[0]); k = kmap(s->map[0]->pages[0]);
memmove((uchar*)VA(k), initcode, sizeof initcode); memmove((uchar*)VA(k), initcode, sizeof initcode);

View file

@ -413,7 +413,7 @@ userinit(void)
s = newseg(SG_TEXT, UTZERO, 1); s = newseg(SG_TEXT, UTZERO, 1);
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO); pg = newpage(1, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
k = kmap(s->map[0]->pages[0]); k = kmap(s->map[0]->pages[0]);
memmove(UINT2PTR(VA(k)), initcode, sizeof initcode); memmove(UINT2PTR(VA(k)), initcode, sizeof initcode);

View file

@ -265,10 +265,9 @@ putmmu(uintptr va, uintptr pa, Page* page)
* rather than direct mapped. * rather than direct mapped.
*/ */
cachedwbinv(); cachedwbinv();
if(page->cachectl[0] == PG_TXTFLUSH){ if(page->txtflush){
/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
cacheiinv(); cacheiinv();
page->cachectl[0] = PG_NOFLUSH; page->txtflush = 0;
} }
checkmmu(va, PPN(pa)); checkmmu(va, PPN(pa));
} }

View file

@ -225,7 +225,7 @@ userinit(void)
s = newseg(SG_TEXT, UTZERO, 1); s = newseg(SG_TEXT, UTZERO, 1);
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO); pg = newpage(1, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
k = kmap(s->map[0]->pages[0]); k = kmap(s->map[0]->pages[0]);
memmove((ulong*)VA(k), initcode, sizeof initcode); memmove((ulong*)VA(k), initcode, sizeof initcode);

View file

@ -406,10 +406,9 @@ putmmu(uintptr va, uintptr pa, Page *pg)
* rather than direct mapped. * rather than direct mapped.
*/ */
cachewb(); cachewb();
if(pg->cachectl[0] == PG_TXTFLUSH){ if(pg->txtflush){
/* pio() sets PG_TXTFLUSH whenever a text page has been written */
icacheinvalidate(); icacheinvalidate();
pg->cachectl[0] = PG_NOFLUSH; pg->txtflush = 0;
} }
splx(s); splx(s);

View file

@ -587,7 +587,7 @@ userinit(void)
s->flushme++; s->flushme++;
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO); pg = newpage(1, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
k = kmap(s->map[0]->pages[0]); k = kmap(s->map[0]->pages[0]);
memmove(UINT2PTR(VA(k)), initcode, sizeof initcode); memmove(UINT2PTR(VA(k)), initcode, sizeof initcode);

View file

@ -353,10 +353,9 @@ putmmu(uintptr va, uintptr pa, Page* page)
* rather than direct mapped. * rather than direct mapped.
*/ */
cachedwbinv(); cachedwbinv();
if(page->cachectl[0] == PG_TXTFLUSH){ if(page->txtflush){
/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
cacheiinv(); cacheiinv();
page->cachectl[0] = PG_NOFLUSH; page->txtflush = 0;
} }
//print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x); //print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
} }

View file

@ -198,7 +198,7 @@ userinit(void)
s->flushme++; s->flushme++;
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO); pg = newpage(1, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
k = kmap(s->map[0]->pages[0]); k = kmap(s->map[0]->pages[0]);
memmove((ulong*)VA(k), initcode, sizeof initcode); memmove((ulong*)VA(k), initcode, sizeof initcode);

View file

@ -179,7 +179,6 @@ void
putmmu(uintptr va, uintptr pa, Page *pg) putmmu(uintptr va, uintptr pa, Page *pg)
{ {
int mp; int mp;
char *ctl;
ulong *p, *ep, *q, pteg; ulong *p, *ep, *q, pteg;
ulong vsid, ptehi, x, hash; ulong vsid, ptehi, x, hash;
@ -218,19 +217,10 @@ putmmu(uintptr va, uintptr pa, Page *pg)
q[1] = pa; q[1] = pa;
sync(); sync();
ctl = &pg->cachectl[m->machno]; if(pg->txtflush & (1<<m->machno)){
switch(*ctl) {
case PG_NEWCOL:
default:
panic("putmmu: %d\n", *ctl);
break;
case PG_NOFLUSH:
break;
case PG_TXTFLUSH:
dcflush((void*)pg->va, BY2PG); dcflush((void*)pg->va, BY2PG);
icflush((void*)pg->va, BY2PG); icflush((void*)pg->va, BY2PG);
*ctl = PG_NOFLUSH; pg->txtflush &= ~(1<<m->machno);
break;
} }
} }

View file

@ -565,7 +565,7 @@ userinit(void)
s = newseg(SG_TEXT, UTZERO, 1); s = newseg(SG_TEXT, UTZERO, 1);
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO); pg = newpage(1, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
k = kmap(s->map[0]->pages[0]); k = kmap(s->map[0]->pages[0]);
memmove(UINT2PTR(VA(k)), initcode, sizeof initcode); memmove(UINT2PTR(VA(k)), initcode, sizeof initcode);

View file

@ -330,10 +330,9 @@ putmmu(uintptr va, uintptr pa, Page* page)
* rather than direct mapped. * rather than direct mapped.
*/ */
cachedwbinv(); cachedwbinv();
if(page->cachectl[0] == PG_TXTFLUSH){ if(page->txtflush){
/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
cacheiinv(); cacheiinv();
page->cachectl[0] = PG_NOFLUSH; page->txtflush = 0;
} }
//print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x); //print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
} }

View file

@ -134,7 +134,7 @@ userinit(void)
s->flushme++; s->flushme++;
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(0, 0, UTZERO); pg = newpage(0, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
v = vmap(pg->pa, BY2PG); v = vmap(pg->pa, BY2PG);
memset(v, 0, BY2PG); memset(v, 0, BY2PG);

View file

@ -307,7 +307,7 @@ userinit(void)
s->flushme++; s->flushme++;
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(0, 0, UTZERO); pg = newpage(0, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
v = tmpmap(pg); v = tmpmap(pg);
memset(v, 0, BY2PG); memset(v, 0, BY2PG);

View file

@ -461,7 +461,7 @@ userinit(void)
s->flushme++; s->flushme++;
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(0, 0, UTZERO); pg = newpage(0, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
v = kmap(pg); v = kmap(pg);
memset(v, 0, BY2PG); memset(v, 0, BY2PG);

View file

@ -1580,12 +1580,12 @@ procctlmemio(Proc *p, uintptr offset, int n, void *va, int read)
memmove(b, a, n); memmove(b, a, n);
kunmap(k); kunmap(k);
/* Ensure the process sees text page changes */ if(!read){
if(s->flushme) /* Ensure the process sees text page changes */
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); if(s->flushme)
pg->txtflush = ~0;
if(!read)
p->newtlb = 1; p->newtlb = 1;
}
qunlock(s); qunlock(s);
poperror(); poperror();

View file

@ -187,7 +187,7 @@ retry:
done: done:
putpage(new); putpage(new);
if(s->flushme) if(s->flushme)
memset((*p)->cachectl, PG_TXTFLUSH, sizeof((*p)->cachectl)); (*p)->txtflush = ~0;
} }
void (*checkaddr)(uintptr, Segment *, Page *); void (*checkaddr)(uintptr, Segment *, Page *);
@ -263,6 +263,8 @@ fixfault(Segment *s, uintptr addr, int read, int doputmmu)
new = newpage(0, &s, addr); new = newpage(0, &s, addr);
if(s == nil) if(s == nil)
return -1; return -1;
if(s->flushme)
new->txtflush = ~0;
*pg = new; *pg = new;
copypage(old, *pg); copypage(old, *pg);
putpage(old); putpage(old);

View file

@ -145,8 +145,7 @@ newpage(int clear, Segment **s, uintptr va)
{ {
Page *p, **l; Page *p, **l;
KMap *k; KMap *k;
uchar ct; int color;
int i, color;
color = getpgcolor(va); color = getpgcolor(va);
lock(&palloc); lock(&palloc);
@ -195,12 +194,9 @@ newpage(int clear, Segment **s, uintptr va)
l = &p->next; l = &p->next;
} }
ct = PG_NOFLUSH;
if(p == nil) { if(p == nil) {
l = &palloc.head; l = &palloc.head;
p = *l; p = *l;
p->color = color;
ct = PG_NEWCOL;
} }
*l = p->next; *l = p->next;
@ -211,8 +207,7 @@ newpage(int clear, Segment **s, uintptr va)
p->ref = 1; p->ref = 1;
p->va = va; p->va = va;
p->modref = 0; p->modref = 0;
for(i = 0; i < MAXMACH; i++) p->txtflush = 0;
p->cachectl[i] = ct;
if(clear) { if(clear) {
k = kmap(p); k = kmap(p);

View file

@ -292,11 +292,6 @@ struct Note
enum enum
{ {
PG_NOFLUSH = 0,
PG_TXTFLUSH = 1, /* flush dcache and invalidate icache */
PG_DATFLUSH = 2, /* flush both i & d caches (UNUSED) */
PG_NEWCOL = 3, /* page has been recolored */
PG_MOD = 0x01, /* software modified bit */ PG_MOD = 0x01, /* software modified bit */
PG_REF = 0x02, /* software referenced bit */ PG_REF = 0x02, /* software referenced bit */
}; };
@ -309,10 +304,10 @@ struct Page
uintptr va; /* Virtual address for user */ uintptr va; /* Virtual address for user */
uintptr daddr; /* Disc address on swap */ uintptr daddr; /* Disc address on swap */
Image *image; /* Associated text or swap image */ Image *image; /* Associated text or swap image */
ulong txtflush; /* Flush icache for putmmu */
ushort refage; /* Swap reference age */ ushort refage; /* Swap reference age */
char modref; /* Simulated modify/reference bits */ char modref; /* Simulated modify/reference bits */
char color; /* Cache coloring */ char color; /* Cache coloring */
char cachectl[MAXMACH]; /* Cache flushing control for putmmu */
}; };
struct Swapalloc struct Swapalloc

View file

@ -669,7 +669,7 @@ pteflush(Pte *pte, int s, int e)
for(i = s; i < e; i++) { for(i = s; i < e; i++) {
pg = pte->pages[i]; pg = pte->pages[i];
if(!pagedout(pg)) if(!pagedout(pg))
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
} }
} }

View file

@ -233,7 +233,7 @@ userinit(void)
s->flushme++; s->flushme++;
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO); pg = newpage(1, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
k = kmap(s->map[0]->pages[0]); k = kmap(s->map[0]->pages[0]);
memmove((ulong*)VA(k), initcode, sizeof initcode); memmove((ulong*)VA(k), initcode, sizeof initcode);

View file

@ -199,7 +199,6 @@ void
putmmu(uintptr va, uintptr pa, Page *pg) putmmu(uintptr va, uintptr pa, Page *pg)
{ {
int mp; int mp;
char *ctl;
ulong *p, *ep, *q, pteg; ulong *p, *ep, *q, pteg;
ulong vsid, hash; ulong vsid, hash;
ulong ptehi, x; ulong ptehi, x;
@ -244,21 +243,11 @@ putmmu(uintptr va, uintptr pa, Page *pg)
q[0] = ptehi; q[0] = ptehi;
q[1] = pa; q[1] = pa;
ctl = &pg->cachectl[m->machno]; if(pg->txtflush & (1<<m->machno)){
switch(*ctl) {
case PG_NEWCOL:
default:
panic("putmmu: %d\n", *ctl);
break;
case PG_TXTFLUSH:
dcflush((void*)pg->va, BY2PG); dcflush((void*)pg->va, BY2PG);
icflush((void*)pg->va, BY2PG); icflush((void*)pg->va, BY2PG);
*ctl = PG_NOFLUSH; pg->txtflush &= ~(1<<m->machno);
break;
case PG_NOFLUSH:
break;
} }
} }
void void

View file

@ -792,7 +792,7 @@ userinit(void)
s = newseg(SG_TEXT, UTZERO, 1); s = newseg(SG_TEXT, UTZERO, 1);
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO); pg = newpage(1, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
k = kmap(s->map[0]->pages[0]); k = kmap(s->map[0]->pages[0]);
memmove(UINT2PTR(VA(k)), initcode, sizeof initcode); memmove(UINT2PTR(VA(k)), initcode, sizeof initcode);

View file

@ -582,10 +582,9 @@ putmmu(uintptr va, uintptr pa, Page* page)
*/ */
l1cache->wb(); l1cache->wb();
if(page->cachectl[0] == PG_TXTFLUSH){ if(page->txtflush & (1<<m->machno)){
/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
cacheiinv(); cacheiinv();
page->cachectl[0] = PG_NOFLUSH; page->txtflush &= ~(1<<m->machno);
} }
if (Debug) if (Debug)
iprint("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x); iprint("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);

View file

@ -245,7 +245,7 @@ userinit(void)
s->flushme++; s->flushme++;
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(1, 0, UTZERO); pg = newpage(1, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
k = kmap(s->map[0]->pages[0]); k = kmap(s->map[0]->pages[0]);
memmove((ulong*)VA(k), initcode, sizeof initcode); memmove((ulong*)VA(k), initcode, sizeof initcode);

View file

@ -306,7 +306,7 @@ userinit(void)
s->flushme++; s->flushme++;
p->seg[TSEG] = s; p->seg[TSEG] = s;
pg = newpage(0, 0, UTZERO); pg = newpage(0, 0, UTZERO);
memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); pg->txtflush = ~0;
segpage(s, pg); segpage(s, pg);
v = tmpmap(pg->pa); v = tmpmap(pg->pa);

View file

@ -140,7 +140,6 @@ putmmu(uintptr va, uintptr pa, Page *pg)
ulong *e; ulong *e;
ulong *l2; ulong *l2;
PTE old; PTE old;
char *ctl;
uintptr l2p; uintptr l2p;
int s; int s;
@ -180,11 +179,10 @@ putmmu(uintptr va, uintptr pa, Page *pg)
splx(s); splx(s);
if((old & L2VALID) != 0) if((old & L2VALID) != 0)
flushpg((void *) va); flushpg((void *) va);
ctl = &pg->cachectl[m->machno]; if(pg->txtflush & (1<<m->machno)){
if(*ctl == PG_TXTFLUSH){
cleandse((void *) va, (void *) (va + BY2PG)); cleandse((void *) va, (void *) (va + BY2PG));
invalise((void *) va, (void *) (va + BY2PG)); invalise((void *) va, (void *) (va + BY2PG));
*ctl = PG_NOFLUSH; pg->txtflush &= ~(1<<m->machno);
} }
} }