kernel: avoid palloc lock during mmurelease()
Previously, mmurelease() was always called with palloc spinlock held. This is unneccesary for some mmurelease() implementations as they wont release pages to the palloc pool. This change removes pagechainhead() and pagechaindone() and replaces them with just freepages() call, which aquires the palloc lock internally as needed. freepages() avoids holding the palloc lock while walking the linked list of pages, avoding some lock contention.
This commit is contained in:
parent
2fb5fbbd73
commit
29f60cace1
13 changed files with 82 additions and 162 deletions
|
@ -173,17 +173,9 @@ flushmmu(void)
|
||||||
void
|
void
|
||||||
mmurelease(Proc* proc)
|
mmurelease(Proc* proc)
|
||||||
{
|
{
|
||||||
Page *page, *next;
|
|
||||||
|
|
||||||
mmul2empty(proc, 0);
|
mmul2empty(proc, 0);
|
||||||
for(page = proc->mmul2cache; page != nil; page = next){
|
|
||||||
next = page->next;
|
freepages(proc->mmul2cache, nil, 0);
|
||||||
if(--page->ref)
|
|
||||||
panic("mmurelease: page->ref %lud", page->ref);
|
|
||||||
pagechainhead(page);
|
|
||||||
}
|
|
||||||
if(proc->mmul2cache != nil)
|
|
||||||
pagechaindone();
|
|
||||||
proc->mmul2cache = nil;
|
proc->mmul2cache = nil;
|
||||||
|
|
||||||
mmul1empty();
|
mmul1empty();
|
||||||
|
|
|
@ -518,20 +518,10 @@ mmuswitch(Proc *p)
|
||||||
void
|
void
|
||||||
mmurelease(Proc *p)
|
mmurelease(Proc *p)
|
||||||
{
|
{
|
||||||
Page *t;
|
|
||||||
|
|
||||||
mmuswitch(nil);
|
mmuswitch(nil);
|
||||||
mmufree(p);
|
mmufree(p);
|
||||||
|
freepages(p->mmufree, nil, 0);
|
||||||
if((t = p->mmufree) != nil){
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -197,23 +197,21 @@ flushmmu(void)
|
||||||
void
|
void
|
||||||
mmurelease(Proc *proc)
|
mmurelease(Proc *proc)
|
||||||
{
|
{
|
||||||
Page *p, *n;
|
Page *p;
|
||||||
|
|
||||||
if(islo())
|
|
||||||
panic("mmurelease: islo");
|
|
||||||
|
|
||||||
l1switch(&m->l1, 0);
|
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)
|
if(proc->l1 == nil)
|
||||||
panic("mmurelease: no l1");
|
panic("mmurelease: no l1");
|
||||||
if(decref(proc->kmaptable) != 0)
|
|
||||||
panic("mmurelease: kmap ref %ld", proc->kmaptable->ref);
|
|
||||||
if(proc->nkmap)
|
if(proc->nkmap)
|
||||||
panic("mmurelease: nkmap %d", proc->nkmap);
|
panic("mmurelease: nkmap %d", proc->nkmap);
|
||||||
if(PPN(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)], proc->kmaptable->pa);
|
panic("mmurelease: bad kmap l2 %#.8lux kmap %#.8lux", proc->l1->va[L1X(KMAP)], p->pa);
|
||||||
proc->l1->va[L1X(KMAP)] = 0;
|
proc->l1->va[L1X(KMAP)] = 0;
|
||||||
pagechainhead(proc->kmaptable);
|
p->next = proc->mmufree;
|
||||||
|
proc->mmufree = p;
|
||||||
proc->kmaptable = nil;
|
proc->kmaptable = nil;
|
||||||
}
|
}
|
||||||
if(proc->l1 != nil){
|
if(proc->l1 != nil){
|
||||||
|
@ -221,14 +219,7 @@ mmurelease(Proc *proc)
|
||||||
l1free(proc->l1);
|
l1free(proc->l1);
|
||||||
proc->l1 = nil;
|
proc->l1 = nil;
|
||||||
}
|
}
|
||||||
for(p = proc->mmufree; p != nil; p = n){
|
freepages(proc->mmufree, nil, 0);
|
||||||
n = p->next;
|
|
||||||
if(decref(p) != 0)
|
|
||||||
panic("mmurelease: p->ref %ld", p->ref);
|
|
||||||
pagechainhead(p);
|
|
||||||
}
|
|
||||||
if(proc->mmufree != nil)
|
|
||||||
pagechaindone();
|
|
||||||
proc->mmufree = nil;
|
proc->mmufree = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,20 +252,12 @@ flushmmu(void)
|
||||||
void
|
void
|
||||||
mmurelease(Proc* proc)
|
mmurelease(Proc* proc)
|
||||||
{
|
{
|
||||||
Page *page, *next;
|
|
||||||
|
|
||||||
/* write back dirty and invalidate l1 caches */
|
/* write back dirty and invalidate l1 caches */
|
||||||
cacheuwbinv();
|
cacheuwbinv();
|
||||||
|
|
||||||
mmul2empty(proc, 0);
|
mmul2empty(proc, 0);
|
||||||
for(page = proc->mmul2cache; page != nil; page = next){
|
|
||||||
next = page->next;
|
freepages(proc->mmul2cache, nil, 0);
|
||||||
if(--page->ref)
|
|
||||||
panic("mmurelease: page->ref %lud", page->ref);
|
|
||||||
pagechainhead(page);
|
|
||||||
}
|
|
||||||
if(proc->mmul2cache != nil)
|
|
||||||
pagechaindone();
|
|
||||||
proc->mmul2cache = nil;
|
proc->mmul2cache = nil;
|
||||||
|
|
||||||
mmul1empty();
|
mmul1empty();
|
||||||
|
|
|
@ -234,20 +234,12 @@ flushmmu(void)
|
||||||
void
|
void
|
||||||
mmurelease(Proc* proc)
|
mmurelease(Proc* proc)
|
||||||
{
|
{
|
||||||
Page *page, *next;
|
|
||||||
|
|
||||||
/* write back dirty and invalidate l1 caches */
|
/* write back dirty and invalidate l1 caches */
|
||||||
cacheuwbinv();
|
cacheuwbinv();
|
||||||
|
|
||||||
mmul2empty(proc, 0);
|
mmul2empty(proc, 0);
|
||||||
for(page = proc->mmul2cache; page != nil; page = next){
|
|
||||||
next = page->next;
|
freepages(proc->mmul2cache, nil, 0);
|
||||||
if(--page->ref)
|
|
||||||
panic("mmurelease: page->ref %ld", page->ref);
|
|
||||||
pagechainhead(page);
|
|
||||||
}
|
|
||||||
if(proc->mmul2cache != nil)
|
|
||||||
pagechaindone();
|
|
||||||
proc->mmul2cache = nil;
|
proc->mmul2cache = nil;
|
||||||
|
|
||||||
mmul1empty();
|
mmul1empty();
|
||||||
|
|
|
@ -320,54 +320,48 @@ mmuswitch(Proc* proc)
|
||||||
* cleaning any user entries in the pdb (proc->mmupdb);
|
* cleaning any user entries in the pdb (proc->mmupdb);
|
||||||
* if there's a pdb put it in the cache of pre-initialised pdb's
|
* 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;
|
* for this processor (m->pdbpool) or on the process' free list;
|
||||||
* finally, place any pages freed back into the free pool (palloc).
|
* finally, place any pages freed back into the free pool (freepages).
|
||||||
* This routine is only called from schedinit() with palloc locked.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
mmurelease(Proc* proc)
|
mmurelease(Proc* proc)
|
||||||
{
|
{
|
||||||
Page *page, *next;
|
|
||||||
ulong *pdb;
|
ulong *pdb;
|
||||||
|
Page *page;
|
||||||
|
|
||||||
if(islo())
|
|
||||||
panic("mmurelease: islo");
|
|
||||||
taskswitch(PADDR(m->pdb), (ulong)m + BY2PG);
|
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)
|
if(proc->mmupdb == nil)
|
||||||
panic("mmurelease: no mmupdb");
|
panic("mmurelease: no mmupdb");
|
||||||
if(--proc->kmaptable->ref != 0)
|
|
||||||
panic("mmurelease: kmap ref %ld", proc->kmaptable->ref);
|
|
||||||
if(proc->nkmap)
|
if(proc->nkmap)
|
||||||
panic("mmurelease: nkmap %d", proc->nkmap);
|
panic("mmurelease: nkmap %d", proc->nkmap);
|
||||||
/*
|
/*
|
||||||
* remove kmaptable from pdb before putting pdb up for reuse.
|
* remove kmaptable from pdb before putting pdb up for reuse.
|
||||||
*/
|
*/
|
||||||
pdb = tmpmap(proc->mmupdb);
|
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",
|
panic("mmurelease: bad kmap pde %#.8lux kmap %#.8lux",
|
||||||
pdb[PDX(KMAP)], proc->kmaptable->pa);
|
pdb[PDX(KMAP)], page->pa);
|
||||||
pdb[PDX(KMAP)] = 0;
|
pdb[PDX(KMAP)] = 0;
|
||||||
tmpunmap(pdb);
|
tmpunmap(pdb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* move kmaptable to free list.
|
* move kmaptable to free list.
|
||||||
*/
|
*/
|
||||||
pagechainhead(proc->kmaptable);
|
page->next = proc->mmufree;
|
||||||
|
proc->mmufree = page;
|
||||||
proc->kmaptable = nil;
|
proc->kmaptable = nil;
|
||||||
}
|
}
|
||||||
if(proc->mmupdb != nil){
|
if((page = proc->mmupdb) != nil){
|
||||||
mmuptefree(proc);
|
mmuptefree(proc);
|
||||||
mmupdbfree(proc, proc->mmupdb);
|
mmupdbfree(proc, page);
|
||||||
proc->mmupdb = nil;
|
proc->mmupdb = nil;
|
||||||
}
|
}
|
||||||
for(page = proc->mmufree; page != nil; page = next){
|
if((page = proc->mmufree) != nil){
|
||||||
next = page->next;
|
freepages(page, nil, 0);
|
||||||
if(--page->ref != 0)
|
proc->mmufree = nil;
|
||||||
panic("mmurelease: page->ref %ld", page->ref);
|
|
||||||
pagechainhead(page);
|
|
||||||
}
|
}
|
||||||
if(proc->mmufree != nil)
|
|
||||||
pagechaindone();
|
|
||||||
proc->mmufree = nil;
|
|
||||||
if(proc->ldt != nil){
|
if(proc->ldt != nil){
|
||||||
free(proc->ldt);
|
free(proc->ldt);
|
||||||
proc->ldt = nil;
|
proc->ldt = nil;
|
||||||
|
|
|
@ -469,7 +469,7 @@ fixedseg(uintptr va, ulong len)
|
||||||
{
|
{
|
||||||
KMap *k;
|
KMap *k;
|
||||||
Segment *s;
|
Segment *s;
|
||||||
Page **f, *p, *l, *h;
|
Page **f, *p, *l, *h, *t;
|
||||||
ulong n, i;
|
ulong n, i;
|
||||||
int color;
|
int color;
|
||||||
|
|
||||||
|
@ -492,12 +492,13 @@ fixedseg(uintptr va, ulong len)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
h = nil;
|
h = t = nil;
|
||||||
f = &palloc.head;
|
f = &palloc.head;
|
||||||
while((p = *f) != nil){
|
while((p = *f) != nil){
|
||||||
if(p > &l[-len] && p <= l){
|
if(p > &l[-len] && p <= l){
|
||||||
*f = p->next;
|
*f = p->next;
|
||||||
p->next = h;
|
if((p->next = h) == nil)
|
||||||
|
t = p;
|
||||||
h = p;
|
h = p;
|
||||||
if(++i < len)
|
if(++i < len)
|
||||||
continue;
|
continue;
|
||||||
|
@ -505,15 +506,15 @@ fixedseg(uintptr va, ulong len)
|
||||||
}
|
}
|
||||||
f = &p->next;
|
f = &p->next;
|
||||||
}
|
}
|
||||||
palloc.freecount -= i;
|
|
||||||
|
|
||||||
if(i != len){
|
if(i != len){
|
||||||
while((p = h) != nil){
|
if(h != nil){
|
||||||
h = h->next;
|
t->next = palloc.head;
|
||||||
pagechainhead(p);
|
palloc.head = h;
|
||||||
}
|
}
|
||||||
goto Retry;
|
goto Retry;
|
||||||
}
|
}
|
||||||
|
palloc.freecount -= i;
|
||||||
unlock(&palloc);
|
unlock(&palloc);
|
||||||
|
|
||||||
p = &l[-len];
|
p = &l[-len];
|
||||||
|
|
|
@ -11,7 +11,7 @@ void
|
||||||
pageinit(void)
|
pageinit(void)
|
||||||
{
|
{
|
||||||
int color, i, j;
|
int color, i, j;
|
||||||
Page *p;
|
Page *p, **t;
|
||||||
Pallocmem *pm;
|
Pallocmem *pm;
|
||||||
vlong m, v, u;
|
vlong m, v, u;
|
||||||
|
|
||||||
|
@ -29,8 +29,12 @@ pageinit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
color = 0;
|
color = 0;
|
||||||
|
palloc.freecount = 0;
|
||||||
palloc.head = nil;
|
palloc.head = nil;
|
||||||
|
|
||||||
|
t = &palloc.head;
|
||||||
p = palloc.pages;
|
p = palloc.pages;
|
||||||
|
|
||||||
for(i=0; i<nelem(palloc.mem); i++){
|
for(i=0; i<nelem(palloc.mem); i++){
|
||||||
pm = &palloc.mem[i];
|
pm = &palloc.mem[i];
|
||||||
for(j=0; j<pm->npage; j++){
|
for(j=0; j<pm->npage; j++){
|
||||||
|
@ -40,7 +44,8 @@ pageinit(void)
|
||||||
continue;
|
continue;
|
||||||
p->color = color;
|
p->color = color;
|
||||||
color = (color+1)%NCOLOR;
|
color = (color+1)%NCOLOR;
|
||||||
pagechainhead(p);
|
*t = p, t = &p->next;
|
||||||
|
palloc.freecount++;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,15 +70,7 @@ pageinit(void)
|
||||||
print("%lldM swap\n", v/(1024*1024));
|
print("%lldM swap\n", v/(1024*1024));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
pagechainhead(Page *p)
|
|
||||||
{
|
|
||||||
p->next = palloc.head;
|
|
||||||
palloc.head = p;
|
|
||||||
palloc.freecount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pagechaindone(void)
|
pagechaindone(void)
|
||||||
{
|
{
|
||||||
if(palloc.pwait[0].p != nil && wakeup(&palloc.pwait[0]) != nil)
|
if(palloc.pwait[0].p != nil && wakeup(&palloc.pwait[0]) != nil)
|
||||||
|
@ -85,11 +82,23 @@ pagechaindone(void)
|
||||||
void
|
void
|
||||||
freepages(Page *head, Page *tail, ulong np)
|
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;
|
tail->next = palloc.head;
|
||||||
palloc.head = head;
|
palloc.head = head;
|
||||||
palloc.freecount += np;
|
palloc.freecount += np;
|
||||||
pagechaindone();
|
pagechaindone();
|
||||||
|
unlock(&palloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong
|
ulong
|
||||||
|
@ -138,11 +147,8 @@ pagereclaim(Image *i)
|
||||||
}
|
}
|
||||||
putimage(i);
|
putimage(i);
|
||||||
|
|
||||||
if(np > 0){
|
if(np > 0)
|
||||||
lock(&palloc);
|
|
||||||
freepages(fh, ft, np);
|
freepages(fh, ft, np);
|
||||||
unlock(&palloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return np;
|
return np;
|
||||||
}
|
}
|
||||||
|
@ -237,11 +243,8 @@ putpage(Page *p)
|
||||||
decref(p);
|
decref(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(decref(p) == 0){
|
if(decref(p) == 0)
|
||||||
lock(&palloc);
|
|
||||||
freepages(p, p, 1);
|
freepages(p, p, 1);
|
||||||
unlock(&palloc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -218,8 +218,6 @@ int okaddr(uintptr, ulong, int);
|
||||||
int openmode(ulong);
|
int openmode(ulong);
|
||||||
Block* packblock(Block*);
|
Block* packblock(Block*);
|
||||||
Block* padblock(Block*, int);
|
Block* padblock(Block*, int);
|
||||||
void pagechaindone(void);
|
|
||||||
void pagechainhead(Page*);
|
|
||||||
void pageinit(void);
|
void pageinit(void);
|
||||||
ulong pagereclaim(Image*);
|
ulong pagereclaim(Image*);
|
||||||
void panic(char*, ...);
|
void panic(char*, ...);
|
||||||
|
|
|
@ -81,27 +81,21 @@ schedinit(void) /* never returns */
|
||||||
case Moribund:
|
case Moribund:
|
||||||
up->state = Dead;
|
up->state = Dead;
|
||||||
edfstop(up);
|
edfstop(up);
|
||||||
if(up->edf != nil)
|
if(up->edf != nil){
|
||||||
free(up->edf);
|
free(up->edf);
|
||||||
up->edf = nil;
|
up->edf = nil;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Holding locks from pexit:
|
|
||||||
* procalloc
|
|
||||||
* palloc
|
|
||||||
*/
|
|
||||||
mmurelease(up);
|
mmurelease(up);
|
||||||
unlock(&palloc);
|
|
||||||
|
|
||||||
updatecpu(up);
|
lock(&procalloc);
|
||||||
up->mach = nil;
|
up->mach = nil;
|
||||||
|
|
||||||
up->qnext = procalloc.free;
|
up->qnext = procalloc.free;
|
||||||
procalloc.free = up;
|
procalloc.free = up;
|
||||||
|
|
||||||
/* proc is free now, make sure unlock() wont touch it */
|
/* proc is free now, make sure unlock() wont touch it */
|
||||||
up = procalloc.Lock.p = nil;
|
up = procalloc.Lock.p = nil;
|
||||||
unlock(&procalloc);
|
unlock(&procalloc);
|
||||||
|
|
||||||
sched();
|
sched();
|
||||||
}
|
}
|
||||||
coherence();
|
coherence();
|
||||||
|
@ -1223,10 +1217,6 @@ pexit(char *exitstr, int freemem)
|
||||||
}
|
}
|
||||||
qunlock(&up->seglock);
|
qunlock(&up->seglock);
|
||||||
|
|
||||||
/* Sched must not loop for these locks */
|
|
||||||
lock(&procalloc);
|
|
||||||
lock(&palloc);
|
|
||||||
|
|
||||||
edfstop(up);
|
edfstop(up);
|
||||||
up->state = Moribund;
|
up->state = Moribund;
|
||||||
sched();
|
sched();
|
||||||
|
|
|
@ -475,20 +475,12 @@ flushmmu(void)
|
||||||
void
|
void
|
||||||
mmurelease(Proc* proc)
|
mmurelease(Proc* proc)
|
||||||
{
|
{
|
||||||
Page *page, *next;
|
|
||||||
|
|
||||||
/* write back dirty and invalidate caches */
|
/* write back dirty and invalidate caches */
|
||||||
l1cache->wbinv();
|
l1cache->wbinv();
|
||||||
|
|
||||||
mmul2empty(proc, 0);
|
mmul2empty(proc, 0);
|
||||||
for(page = proc->mmul2cache; page != nil; page = next){
|
|
||||||
next = page->next;
|
freepages(proc->mmul2cache, nil, 0);
|
||||||
if(--page->ref)
|
|
||||||
panic("mmurelease: page->ref %ld", page->ref);
|
|
||||||
pagechainhead(page);
|
|
||||||
}
|
|
||||||
if(proc->mmul2cache != nil)
|
|
||||||
pagechaindone();
|
|
||||||
proc->mmul2cache = nil;
|
proc->mmul2cache = nil;
|
||||||
|
|
||||||
mmul1empty();
|
mmul1empty();
|
||||||
|
|
|
@ -282,15 +282,8 @@ mmurelease(Proc* proc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(page = proc->mmufree; page; page = next){
|
freepages(proc->mmufree, nil, 0);
|
||||||
next = page->next;
|
proc->mmufree = nil;
|
||||||
if(--page->ref)
|
|
||||||
panic("mmurelease: page->ref %ld\n", page->ref);
|
|
||||||
pagechainhead(page);
|
|
||||||
}
|
|
||||||
if(proc->mmufree)
|
|
||||||
pagechaindone();
|
|
||||||
proc->mmufree = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Page*
|
static Page*
|
||||||
|
|
|
@ -205,23 +205,22 @@ flushmmu(void)
|
||||||
void
|
void
|
||||||
mmurelease(Proc *proc)
|
mmurelease(Proc *proc)
|
||||||
{
|
{
|
||||||
Page *p, *n;
|
Page *p;
|
||||||
|
|
||||||
if(islo())
|
|
||||||
panic("mmurelease: islo");
|
|
||||||
|
|
||||||
l1switch(&m->l1, 0);
|
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)
|
if(proc->l1 == nil)
|
||||||
panic("mmurelease: no l1");
|
panic("mmurelease: no l1");
|
||||||
if(decref(proc->kmaptable) != 0)
|
|
||||||
panic("mmurelease: kmap ref %ld", proc->kmaptable->ref);
|
|
||||||
if(proc->nkmap)
|
if(proc->nkmap)
|
||||||
panic("mmurelease: nkmap %d", proc->nkmap);
|
panic("mmurelease: nkmap %d", proc->nkmap);
|
||||||
if(PPN(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)], proc->kmaptable->pa);
|
panic("mmurelease: bad kmap l2 %#.8lux kmap %#.8lux", proc->l1->va[L1X(KMAP)], p->pa);
|
||||||
proc->l1->va[L1X(KMAP)] = 0;
|
proc->l1->va[L1X(KMAP)] = 0;
|
||||||
pagechainhead(proc->kmaptable);
|
|
||||||
|
p->next = proc->mmufree;
|
||||||
|
proc->mmufree = p;
|
||||||
proc->kmaptable = nil;
|
proc->kmaptable = nil;
|
||||||
}
|
}
|
||||||
if(proc->l1 != nil){
|
if(proc->l1 != nil){
|
||||||
|
@ -229,14 +228,7 @@ mmurelease(Proc *proc)
|
||||||
l1free(proc->l1);
|
l1free(proc->l1);
|
||||||
proc->l1 = nil;
|
proc->l1 = nil;
|
||||||
}
|
}
|
||||||
for(p = proc->mmufree; p != nil; p = n){
|
freepages(proc->mmufree, nil, 0);
|
||||||
n = p->next;
|
|
||||||
if(decref(p) != 0)
|
|
||||||
panic("mmurelease: p->ref %ld", p->ref);
|
|
||||||
pagechainhead(p);
|
|
||||||
}
|
|
||||||
if(proc->mmufree != nil)
|
|
||||||
pagechaindone();
|
|
||||||
proc->mmufree = nil;
|
proc->mmufree = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue