summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/bcm/mmu.c12
-rw-r--r--sys/src/9/bcm64/mmu.c14
-rw-r--r--sys/src/9/cycv/mmu.c27
-rw-r--r--sys/src/9/kw/mmu.c12
-rw-r--r--sys/src/9/omap/mmu.c12
-rw-r--r--sys/src/9/pc/mmu.c36
-rw-r--r--sys/src/9/port/devsegment.c15
-rw-r--r--sys/src/9/port/page.c43
-rw-r--r--sys/src/9/port/portfns.h2
-rw-r--r--sys/src/9/port/proc.c20
-rw-r--r--sys/src/9/teg2/mmu.c12
-rw-r--r--sys/src/9/xen/mmu.c11
-rw-r--r--sys/src/9/zynq/mmu.c28
13 files changed, 82 insertions, 162 deletions
diff --git a/sys/src/9/bcm/mmu.c b/sys/src/9/bcm/mmu.c
index 864757079..655d847ae 100644
--- a/sys/src/9/bcm/mmu.c
+++ b/sys/src/9/bcm/mmu.c
@@ -173,17 +173,9 @@ flushmmu(void)
void
mmurelease(Proc* proc)
{
- Page *page, *next;
-
mmul2empty(proc, 0);
- for(page = proc->mmul2cache; page != nil; page = next){
- next = page->next;
- if(--page->ref)
- panic("mmurelease: page->ref %lud", page->ref);
- pagechainhead(page);
- }
- if(proc->mmul2cache != nil)
- pagechaindone();
+
+ freepages(proc->mmul2cache, nil, 0);
proc->mmul2cache = nil;
mmul1empty();
diff --git a/sys/src/9/bcm64/mmu.c b/sys/src/9/bcm64/mmu.c
index 4c664554b..8538369fa 100644
--- a/sys/src/9/bcm64/mmu.c
+++ b/sys/src/9/bcm64/mmu.c
@@ -518,20 +518,10 @@ mmuswitch(Proc *p)
void
mmurelease(Proc *p)
{
- Page *t;
-
mmuswitch(nil);
mmufree(p);
-
- if((t = p->mmufree) != nil){
- do {
- p->mmufree = t->next;
- if(--t->ref != 0)
- panic("mmurelease: bad page ref");
- pagechainhead(t);
- } while((t = p->mmufree) != nil);
- pagechaindone();
- }
+ freepages(p->mmufree, nil, 0);
+ p->mmufree = nil;
}
void
diff --git a/sys/src/9/cycv/mmu.c b/sys/src/9/cycv/mmu.c
index 8a449e70b..213a88178 100644
--- a/sys/src/9/cycv/mmu.c
+++ b/sys/src/9/cycv/mmu.c
@@ -197,23 +197,21 @@ flushmmu(void)
void
mmurelease(Proc *proc)
{
- Page *p, *n;
+ Page *p;
- if(islo())
- panic("mmurelease: islo");
-
l1switch(&m->l1, 0);
- if(proc->kmaptable != nil){
+ if((p = proc->kmaptable) != nil){
+ if(p->ref != 1)
+ panic("mmurelease: kmap ref %ld", p->ref);
if(proc->l1 == nil)
panic("mmurelease: no l1");
- if(decref(proc->kmaptable) != 0)
- panic("mmurelease: kmap ref %ld", proc->kmaptable->ref);
if(proc->nkmap)
panic("mmurelease: nkmap %d", proc->nkmap);
- if(PPN(proc->l1->va[L1X(KMAP)]) != proc->kmaptable->pa)
- panic("mmurelease: bad kmap l2 %#.8lux kmap %#.8lux", proc->l1->va[L1X(KMAP)], proc->kmaptable->pa);
+ if(PPN(proc->l1->va[L1X(KMAP)]) != p->pa)
+ panic("mmurelease: bad kmap l2 %#.8lux kmap %#.8lux", proc->l1->va[L1X(KMAP)], p->pa);
proc->l1->va[L1X(KMAP)] = 0;
- pagechainhead(proc->kmaptable);
+ p->next = proc->mmufree;
+ proc->mmufree = p;
proc->kmaptable = nil;
}
if(proc->l1 != nil){
@@ -221,14 +219,7 @@ mmurelease(Proc *proc)
l1free(proc->l1);
proc->l1 = nil;
}
- for(p = proc->mmufree; p != nil; p = n){
- n = p->next;
- if(decref(p) != 0)
- panic("mmurelease: p->ref %ld", p->ref);
- pagechainhead(p);
- }
- if(proc->mmufree != nil)
- pagechaindone();
+ freepages(proc->mmufree, nil, 0);
proc->mmufree = nil;
}
diff --git a/sys/src/9/kw/mmu.c b/sys/src/9/kw/mmu.c
index bab4238fd..0696bff35 100644
--- a/sys/src/9/kw/mmu.c
+++ b/sys/src/9/kw/mmu.c
@@ -252,20 +252,12 @@ flushmmu(void)
void
mmurelease(Proc* proc)
{
- Page *page, *next;
-
/* write back dirty and invalidate l1 caches */
cacheuwbinv();
mmul2empty(proc, 0);
- for(page = proc->mmul2cache; page != nil; page = next){
- next = page->next;
- if(--page->ref)
- panic("mmurelease: page->ref %lud", page->ref);
- pagechainhead(page);
- }
- if(proc->mmul2cache != nil)
- pagechaindone();
+
+ freepages(proc->mmul2cache, nil, 0);
proc->mmul2cache = nil;
mmul1empty();
diff --git a/sys/src/9/omap/mmu.c b/sys/src/9/omap/mmu.c
index d427f1d76..12383c962 100644
--- a/sys/src/9/omap/mmu.c
+++ b/sys/src/9/omap/mmu.c
@@ -234,20 +234,12 @@ flushmmu(void)
void
mmurelease(Proc* proc)
{
- Page *page, *next;
-
/* write back dirty and invalidate l1 caches */
cacheuwbinv();
mmul2empty(proc, 0);
- for(page = proc->mmul2cache; page != nil; page = next){
- next = page->next;
- if(--page->ref)
- panic("mmurelease: page->ref %ld", page->ref);
- pagechainhead(page);
- }
- if(proc->mmul2cache != nil)
- pagechaindone();
+
+ freepages(proc->mmul2cache, nil, 0);
proc->mmul2cache = nil;
mmul1empty();
diff --git a/sys/src/9/pc/mmu.c b/sys/src/9/pc/mmu.c
index df0c23520..a21c94197 100644
--- a/sys/src/9/pc/mmu.c
+++ b/sys/src/9/pc/mmu.c
@@ -320,54 +320,48 @@ mmuswitch(Proc* proc)
* cleaning any user entries in the pdb (proc->mmupdb);
* if there's a pdb put it in the cache of pre-initialised pdb's
* for this processor (m->pdbpool) or on the process' free list;
- * finally, place any pages freed back into the free pool (palloc).
- * This routine is only called from schedinit() with palloc locked.
+ * finally, place any pages freed back into the free pool (freepages).
*/
void
mmurelease(Proc* proc)
{
- Page *page, *next;
ulong *pdb;
+ Page *page;
- if(islo())
- panic("mmurelease: islo");
taskswitch(PADDR(m->pdb), (ulong)m + BY2PG);
- if(proc->kmaptable != nil){
+ if((page = proc->kmaptable) != nil){
+ if(page->ref != 1)
+ panic("mmurelease: kmap ref %ld", page->ref);
if(proc->mmupdb == nil)
panic("mmurelease: no mmupdb");
- if(--proc->kmaptable->ref != 0)
- panic("mmurelease: kmap ref %ld", proc->kmaptable->ref);
if(proc->nkmap)
panic("mmurelease: nkmap %d", proc->nkmap);
/*
* remove kmaptable from pdb before putting pdb up for reuse.
*/
pdb = tmpmap(proc->mmupdb);
- if(PPN(pdb[PDX(KMAP)]) != proc->kmaptable->pa)
+ if(PPN(pdb[PDX(KMAP)]) != page->pa)
panic("mmurelease: bad kmap pde %#.8lux kmap %#.8lux",
- pdb[PDX(KMAP)], proc->kmaptable->pa);
+ pdb[PDX(KMAP)], page->pa);
pdb[PDX(KMAP)] = 0;
tmpunmap(pdb);
+
/*
* move kmaptable to free list.
*/
- pagechainhead(proc->kmaptable);
+ page->next = proc->mmufree;
+ proc->mmufree = page;
proc->kmaptable = nil;
}
- if(proc->mmupdb != nil){
+ if((page = proc->mmupdb) != nil){
mmuptefree(proc);
- mmupdbfree(proc, proc->mmupdb);
+ mmupdbfree(proc, page);
proc->mmupdb = nil;
}
- for(page = proc->mmufree; page != nil; page = next){
- next = page->next;
- if(--page->ref != 0)
- panic("mmurelease: page->ref %ld", page->ref);
- pagechainhead(page);
+ if((page = proc->mmufree) != nil){
+ freepages(page, nil, 0);
+ proc->mmufree = nil;
}
- if(proc->mmufree != nil)
- pagechaindone();
- proc->mmufree = nil;
if(proc->ldt != nil){
free(proc->ldt);
proc->ldt = nil;
diff --git a/sys/src/9/port/devsegment.c b/sys/src/9/port/devsegment.c
index fcaf8f3e4..dfbd34fbf 100644
--- a/sys/src/9/port/devsegment.c
+++ b/sys/src/9/port/devsegment.c
@@ -469,7 +469,7 @@ fixedseg(uintptr va, ulong len)
{
KMap *k;
Segment *s;
- Page **f, *p, *l, *h;
+ Page **f, *p, *l, *h, *t;
ulong n, i;
int color;
@@ -492,12 +492,13 @@ fixedseg(uintptr va, ulong len)
continue;
i = 0;
- h = nil;
+ h = t = nil;
f = &palloc.head;
while((p = *f) != nil){
if(p > &l[-len] && p <= l){
*f = p->next;
- p->next = h;
+ if((p->next = h) == nil)
+ t = p;
h = p;
if(++i < len)
continue;
@@ -505,15 +506,15 @@ fixedseg(uintptr va, ulong len)
}
f = &p->next;
}
- palloc.freecount -= i;
if(i != len){
- while((p = h) != nil){
- h = h->next;
- pagechainhead(p);
+ if(h != nil){
+ t->next = palloc.head;
+ palloc.head = h;
}
goto Retry;
}
+ palloc.freecount -= i;
unlock(&palloc);
p = &l[-len];
diff --git a/sys/src/9/port/page.c b/sys/src/9/port/page.c
index 0a039c099..b7194058e 100644
--- a/sys/src/9/port/page.c
+++ b/sys/src/9/port/page.c
@@ -11,7 +11,7 @@ void
pageinit(void)
{
int color, i, j;
- Page *p;
+ Page *p, **t;
Pallocmem *pm;
vlong m, v, u;
@@ -29,8 +29,12 @@ pageinit(void)
}
color = 0;
+ palloc.freecount = 0;
palloc.head = nil;
+
+ t = &palloc.head;
p = palloc.pages;
+
for(i=0; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
for(j=0; j<pm->npage; j++){
@@ -40,7 +44,8 @@ pageinit(void)
continue;
p->color = color;
color = (color+1)%NCOLOR;
- pagechainhead(p);
+ *t = p, t = &p->next;
+ palloc.freecount++;
p++;
}
}
@@ -65,15 +70,7 @@ pageinit(void)
print("%lldM swap\n", v/(1024*1024));
}
-void
-pagechainhead(Page *p)
-{
- p->next = palloc.head;
- palloc.head = p;
- palloc.freecount++;
-}
-
-void
+static void
pagechaindone(void)
{
if(palloc.pwait[0].p != nil && wakeup(&palloc.pwait[0]) != nil)
@@ -85,11 +82,23 @@ pagechaindone(void)
void
freepages(Page *head, Page *tail, ulong np)
{
- assert(palloc.Lock.p == up);
+ if(head == nil)
+ return;
+ if(tail == nil){
+ tail = head;
+ for(np = 1;; np++){
+ tail->ref = 0;
+ if(tail->next == nil)
+ break;
+ tail = tail->next;
+ }
+ }
+ lock(&palloc);
tail->next = palloc.head;
palloc.head = head;
palloc.freecount += np;
pagechaindone();
+ unlock(&palloc);
}
ulong
@@ -138,11 +147,8 @@ pagereclaim(Image *i)
}
putimage(i);
- if(np > 0){
- lock(&palloc);
+ if(np > 0)
freepages(fh, ft, np);
- unlock(&palloc);
- }
return np;
}
@@ -237,11 +243,8 @@ putpage(Page *p)
decref(p);
return;
}
- if(decref(p) == 0){
- lock(&palloc);
+ if(decref(p) == 0)
freepages(p, p, 1);
- unlock(&palloc);
- }
}
void
diff --git a/sys/src/9/port/portfns.h b/sys/src/9/port/portfns.h
index d1d2c485c..7446513be 100644
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -218,8 +218,6 @@ int okaddr(uintptr, ulong, int);
int openmode(ulong);
Block* packblock(Block*);
Block* padblock(Block*, int);
-void pagechaindone(void);
-void pagechainhead(Page*);
void pageinit(void);
ulong pagereclaim(Image*);
void panic(char*, ...);
diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c
index a51232d44..567ab0756 100644
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -81,27 +81,21 @@ schedinit(void) /* never returns */
case Moribund:
up->state = Dead;
edfstop(up);
- if(up->edf != nil)
+ if(up->edf != nil){
free(up->edf);
- up->edf = nil;
+ up->edf = nil;
+ }
- /*
- * Holding locks from pexit:
- * procalloc
- * palloc
- */
mmurelease(up);
- unlock(&palloc);
- updatecpu(up);
+ lock(&procalloc);
up->mach = nil;
-
up->qnext = procalloc.free;
procalloc.free = up;
-
/* proc is free now, make sure unlock() wont touch it */
up = procalloc.Lock.p = nil;
unlock(&procalloc);
+
sched();
}
coherence();
@@ -1223,10 +1217,6 @@ pexit(char *exitstr, int freemem)
}
qunlock(&up->seglock);
- /* Sched must not loop for these locks */
- lock(&procalloc);
- lock(&palloc);
-
edfstop(up);
up->state = Moribund;
sched();
diff --git a/sys/src/9/teg2/mmu.c b/sys/src/9/teg2/mmu.c
index 871e1c1c3..6005e5065 100644
--- a/sys/src/9/teg2/mmu.c
+++ b/sys/src/9/teg2/mmu.c
@@ -475,20 +475,12 @@ flushmmu(void)
void
mmurelease(Proc* proc)
{
- Page *page, *next;
-
/* write back dirty and invalidate caches */
l1cache->wbinv();
mmul2empty(proc, 0);
- for(page = proc->mmul2cache; page != nil; page = next){
- next = page->next;
- if(--page->ref)
- panic("mmurelease: page->ref %ld", page->ref);
- pagechainhead(page);
- }
- if(proc->mmul2cache != nil)
- pagechaindone();
+
+ freepages(proc->mmul2cache, nil, 0);
proc->mmul2cache = nil;
mmul1empty();
diff --git a/sys/src/9/xen/mmu.c b/sys/src/9/xen/mmu.c
index 1a5c3d067..250d08371 100644
--- a/sys/src/9/xen/mmu.c
+++ b/sys/src/9/xen/mmu.c
@@ -282,15 +282,8 @@ mmurelease(Proc* proc)
}
}
- for(page = proc->mmufree; page; page = next){
- next = page->next;
- if(--page->ref)
- panic("mmurelease: page->ref %ld\n", page->ref);
- pagechainhead(page);
- }
- if(proc->mmufree)
- pagechaindone();
- proc->mmufree = 0;
+ freepages(proc->mmufree, nil, 0);
+ proc->mmufree = nil;
}
static Page*
diff --git a/sys/src/9/zynq/mmu.c b/sys/src/9/zynq/mmu.c
index ed6412e70..9b4c67d4c 100644
--- a/sys/src/9/zynq/mmu.c
+++ b/sys/src/9/zynq/mmu.c
@@ -205,23 +205,22 @@ flushmmu(void)
void
mmurelease(Proc *proc)
{
- Page *p, *n;
+ Page *p;
- if(islo())
- panic("mmurelease: islo");
-
l1switch(&m->l1, 0);
- if(proc->kmaptable != nil){
+ if((p = proc->kmaptable) != nil){
+ if(p->ref != 1)
+ panic("mmurelease: kmap ref %ld", p->ref);
if(proc->l1 == nil)
panic("mmurelease: no l1");
- if(decref(proc->kmaptable) != 0)
- panic("mmurelease: kmap ref %ld", proc->kmaptable->ref);
if(proc->nkmap)
panic("mmurelease: nkmap %d", proc->nkmap);
- if(PPN(proc->l1->va[L1X(KMAP)]) != proc->kmaptable->pa)
- panic("mmurelease: bad kmap l2 %#.8lux kmap %#.8lux", proc->l1->va[L1X(KMAP)], proc->kmaptable->pa);
+ if(PPN(proc->l1->va[L1X(KMAP)]) != p->pa)
+ panic("mmurelease: bad kmap l2 %#.8lux kmap %#.8lux", proc->l1->va[L1X(KMAP)], p->pa);
proc->l1->va[L1X(KMAP)] = 0;
- pagechainhead(proc->kmaptable);
+
+ p->next = proc->mmufree;
+ proc->mmufree = p;
proc->kmaptable = nil;
}
if(proc->l1 != nil){
@@ -229,14 +228,7 @@ mmurelease(Proc *proc)
l1free(proc->l1);
proc->l1 = nil;
}
- for(p = proc->mmufree; p != nil; p = n){
- n = p->next;
- if(decref(p) != 0)
- panic("mmurelease: p->ref %ld", p->ref);
- pagechainhead(p);
- }
- if(proc->mmufree != nil)
- pagechaindone();
+ freepages(proc->mmufree, nil, 0);
proc->mmufree = nil;
}