ref: db2e22aebe607fafc30c12776aa7efb1169277cd
parent: 47f551bcea708c32e654ab68d1f15a17d0cdde46
author: cinap_lenrek <[email protected]>
date: Sun Feb 2 03:12:08 EST 2014
pc64: fix mmu structure leakage, implement global pool
--- a/sys/src/9/pc64/mmu.c
+++ b/sys/src/9/pc64/mmu.c
@@ -25,6 +25,15 @@
static int didmmuinit = 0;
+static struct {
+ Lock;
+ MMU *free;
+
+ int nshare;
+ int nalloc;
+ int nfree;
+} mmupool;
+
/* level */
enum {
PML4E = 2,
@@ -161,22 +170,40 @@
int i, n;
p = m->mmufree;
- if(p == nil){
- n = 256;
- p = malloc(n * sizeof(MMU));
- if(p == nil)
- panic("mmualloc: out of memory for MMU");
- p->page = mallocalign(n * PTSZ, BY2PG, 0, 0);
- if(p->page == nil)
- panic("mmualloc: out of memory for MMU pages");
- for(i=1; i<n; i++){
- p[i].page = p[i-1].page + (1<<PTSHIFT);
- p[i-1].next = &p[i];
+ if(p != nil){
+ m->mmufree = p->next;
+ m->mmucount--;
+ } else {
+ lock(&mmupool);
+ p = mmupool.free;
+ if(p != nil){
+ mmupool.free = p->next;
+ mmupool.nfree--;
+ } else {
+ unlock(&mmupool);
+
+ n = 256;
+ p = malloc(n * sizeof(MMU));
+ if(p == nil)
+ panic("mmualloc: out of memory for MMU");
+ p->page = mallocalign(n * PTSZ, BY2PG, 0, 0);
+ if(p->page == nil)
+ panic("mmualloc: out of memory for MMU pages");
+ for(i=1; i<n; i++){
+ p[i].page = p[i-1].page + (1<<PTSHIFT);
+ p[i-1].next = &p[i];
+ }
+
+ lock(&mmupool);
+ p[n-1].next = mmupool.free;
+ mmupool.free = p->next;
+ mmupool.nalloc += n;
+ mmupool.nfree += n-1;
+
+ mmupool.nshare = mmupool.nalloc / conf.nmach;
}
- m->mmucount += n;
+ unlock(&mmupool);
}
- m->mmucount--;
- m->mmufree = p->next;
p->next = nil;
return p;
}
@@ -216,7 +243,9 @@
} else {
/* PDP and PD entries linked to tail */
up->mmutail->next = p;
+ up->mmutail = p;
}
+ up->mmucount++;
page = p->page;
} else if(didmmuinit) {
page = mallocalign(PTSZ, BY2PG, 0, 0);
@@ -315,13 +344,21 @@
MMU *p;
p = proc->mmutail;
- if(p != nil){
+ if(p == nil)
+ return;
+ if(m->mmucount < mmupool.nshare){
p->next = m->mmufree;
m->mmufree = proc->mmuhead;
- proc->mmuhead = proc->mmutail = nil;
m->mmucount += proc->mmucount;
- proc->mmucount = 0;
+ } else {
+ lock(&mmupool);
+ p->next = mmupool.free;
+ mmupool.free = proc->mmuhead;
+ mmupool.nfree += proc->mmucount;
+ unlock(&mmupool);
}
+ proc->mmuhead = proc->mmutail = nil;
+ proc->mmucount = 0;
}
void