M pc/mmu.c => pc/mmu.c +17 -13
@@ 183,9 183,12 @@ mmugetpage(int clear)
}
/*
- * Put all page map pages on the process's free list and
+ * Put all bottom level page map pages on the process's free list and
* call mapstack to set up the prototype page map. This
* effectively forgets all of the process's mappings.
+ *
+ * Don't free the top level page. Just zero the used entries. This
+ * avoids a 4k copy each flushmmu.
*/
void
flushmmu(void)
@@ 193,19 196,20 @@ flushmmu(void)
int s;
Proc *p;
Page *pg;
+ ulong *top;
if(u == 0)
return;
p = u->p;
s = splhi();
- if(p->mmutop){
- p->mmutop->next = p->mmufree;
- p->mmufree = p->mmutop;
- for(pg = p->mmufree; pg->next; pg = pg->next)
- ;
- pg->next = p->mmuused;
- p->mmutop = 0;
+ if(p->mmutop && p->mmuused){
+ top = (ulong*)p->mmutop->va;
+ for(pg = p->mmuused; pg->next; pg = pg->next)
+ top[pg->daddr] = 0;
+ top[pg->daddr] = 0;
+ pg->next = p->mmufree;
+ p->mmufree = p->mmuused;
p->mmuused = 0;
}
mapstack(u->p);
@@ 227,15 231,14 @@ mapstack(Proc *p)
if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0)
panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va);
- if(p->mmutop)
- pg = p->mmutop;
- else
- pg = &ktoppg;
-
/* map in u area */
upt[0] = PPN(p->upage->pa) | PTEVALID | PTEKERNEL | PTEWRITE;
/* tell processor about new page table (flushes cached entries) */
+ if(p->mmutop)
+ pg = p->mmutop;
+ else
+ pg = &ktoppg;
putcr3(pg->pa);
u = (User*)USERADDR;
@@ 322,6 325,7 @@ putmmu(ulong va, ulong pa, Page *pg)
top[topoff] = PPN(pg->pa) | PTEVALID | PTEUSER | PTEWRITE;
pg->next = p->mmuused;
p->mmuused = pg;
+ pg->daddr = topoff;
}
/*
M port/page.c => port/page.c +8 -4
@@ 461,7 461,7 @@ ptealloc(void)
while(ptealloclk.free == 0) {
unlock(&ptealloclk);
- k = kmap(newpage(0, 0, 0));
+ k = kmap(newpage(1, 0, 0));
new = (Pte*)VA(k);
n = (BY2PG/sizeof(Pte))-1;
for(i = 0; i < n; i++)
@@ 476,9 476,9 @@ ptealloc(void)
new = ptealloclk.free;
ptealloclk.free = new->next;
unlock(&ptealloclk);
- memset(new->pages, 0, sizeof(new->pages));
new->first = &new->pages[PTEPERTAB];
new->last = new->pages;
+
return new;
}
@@ 491,13 491,17 @@ freepte(Segment *s, Pte *p)
case SG_PHYSICAL:
ptop = &p->pages[PTEPERTAB];
for(pg = p->pages; pg < ptop; pg++)
- if(*pg)
+ if(*pg) {
(*s->pgfree)(*pg);
+ *pg = 0;
+ }
break;
default:
for(pg = p->first; pg <= p->last; pg++)
- if(*pg)
+ if(*pg) {
putpage(*pg);
+ *pg = 0;
+ }
}
lock(&ptealloclk);
M port/portdat.h => port/portdat.h +4 -6
@@ 327,12 327,10 @@ struct Image
struct Pte
{
- union {
- Pte *next; /* Free list */
- Page *pages[PTEPERTAB]; /* Page map for this chunk of pte */
- };
- Page **first; /* First used entry */
- Page **last; /* Last used entry */
+ Page *pages[PTEPERTAB]; /* Page map for this chunk of pte */
+ Page **first; /* First used entry */
+ Page **last; /* Last used entry */
+ Pte *next; /* Free list */
};
/* Segment types */
M port/sysproc.c => port/sysproc.c +1 -1
@@ 49,7 49,7 @@ rfork(ulong flag)
p = newproc();
/* Page va of upage used as check in mapstack */
- p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
+ p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF));
k = kmap(p->upage);
upa = VA(k);