summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/mmu.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2020-12-22 16:29:55 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2020-12-22 16:29:55 +0100
commit29f60cace1a71edd730c60ddac8dfbd962741038 (patch)
tree11967087ec1657d52a90c7508cf73e2e1bcc9307 /sys/src/9/pc/mmu.c
parent2fb5fbbd73a1c861bdc7326ece8035ffb35f7093 (diff)
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.
Diffstat (limited to 'sys/src/9/pc/mmu.c')
-rw-r--r--sys/src/9/pc/mmu.c36
1 files changed, 15 insertions, 21 deletions
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;