From c9f91d50154015ef31b6e63131847742893ffc91 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 1 Jun 2014 03:13:58 +0200 Subject: [PATCH] pc64: allocate palloc.pages from upages the palloc.pages array takes arround 5% of the upages which gives us: 16GB = ~0.8GB 32GB = ~1.6GB 64GB = ~3.2GB we only have 2GB of address space above KZERO so this will not work for long. instead, pageinit() was altered to accept a preallocated memory in palloc.pages. and preallocpages() in pc64/main.c allocates the in upages memory, mapping it in the VMAP area (which has 512GB). the drawback is that we cannot poke at Page structures now from /proc/n/mem as the VMAP area is not accessible from it. --- sys/src/9/pc64/fns.h | 2 +- sys/src/9/pc64/main.c | 42 +++++++++++++++++++++++++++++++++++++++-- sys/src/9/pc64/mem.h | 2 +- sys/src/9/pc64/memory.c | 39 ++------------------------------------ sys/src/9/pc64/mmu.c | 6 +++--- sys/src/9/port/page.c | 20 ++++++++++++-------- 6 files changed, 59 insertions(+), 52 deletions(-) diff --git a/sys/src/9/pc64/fns.h b/sys/src/9/pc64/fns.h index 47c3acf7a..0e2d8263c 100644 --- a/sys/src/9/pc64/fns.h +++ b/sys/src/9/pc64/fns.h @@ -146,7 +146,7 @@ int (*_pcmspecial)(char *, ISAConf *); void pcmspecialclose(int); void (*_pcmspecialclose)(int); void pcmunmap(int, PCMmap*); -void pmap(uintptr *, uintptr, uintptr, int); +void pmap(uintptr *, uintptr, uintptr, vlong); void procrestore(Proc*); void procsave(Proc*); void procsetup(Proc*); diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c index 175fac319..8b5b45338 100644 --- a/sys/src/9/pc64/main.c +++ b/sys/src/9/pc64/main.c @@ -231,8 +231,7 @@ confinit(void) * (probably ~300KB). */ kpages *= BY2PG; - kpages -= conf.upages*sizeof(Page) - + conf.nproc*sizeof(Proc) + kpages -= conf.nproc*sizeof(Proc) + conf.nimage*sizeof(Image) + conf.nswap + conf.nswppo*sizeof(Page*); @@ -250,6 +249,44 @@ confinit(void) } } +/* + * The palloc.pages array takes arround 5% of the amount + * of upages which can be a large chunk out of the 2GB + * window above KZERO, so we allocate the array from + * upages and map in the VMAP window before pageinit() + */ +static void +preallocpages(void) +{ + Pallocmem *pm; + uintptr va; + vlong size; + ulong np; + int i; + + np = 0; + for(i=0; inpage; + } + size = (uvlong)np * BY2PG; + size += sizeof(Page) + BY2PG; /* round up */ + size = (size / (sizeof(Page) + BY2PG)) * sizeof(Page); + size = PGROUND(size); + + np = size/BY2PG; + for(i=0; ibase + size) <= VMAPSIZE && pm->npage >= np){ + va = VMAP + pm->base; + pmap(m->pml4, pm->base | PTEGLOBAL|PTEWRITE|PTEVALID, va, size); + palloc.pages = (Page*)va; + pm->base += size; + pm->npage -= np; + break; + } + } +} void machinit(void) @@ -492,6 +529,7 @@ main() links(); conf.monitor = 1; chandevreset(); + preallocpages(); pageinit(); swapinit(); userinit(); diff --git a/sys/src/9/pc64/mem.h b/sys/src/9/pc64/mem.h index a641f8800..595ade9e3 100644 --- a/sys/src/9/pc64/mem.h +++ b/sys/src/9/pc64/mem.h @@ -56,7 +56,7 @@ #define KTZERO (KZERO+1*MiB+64*KiB) #define VMAP (0xffffff0000000000ull) -#define VMAPSIZE (512*GiB) +#define VMAPSIZE (512ull*GiB) #define KMAP (0xfffffe8000000000ull) #define KMAPSIZE (2*MiB) diff --git a/sys/src/9/pc64/memory.c b/sys/src/9/pc64/memory.c index 37c611e00..1c7759dad 100644 --- a/sys/src/9/pc64/memory.c +++ b/sys/src/9/pc64/memory.c @@ -371,25 +371,6 @@ sigsearch(char* signature) return sigscan(KADDR(0xe0000), 0x20000, signature); } -static void -lowraminit(void) -{ - uintptr pa, x; - - /* - * Initialise the memory bank information for conventional memory - * (i.e. less than 640KB). The base is the first location after the - * bootstrap processor MMU information and the limit is obtained from - * the BIOS data area. - */ - x = PADDR(PGROUND((uintptr)end)); - pa = MemMin; - if(x > pa) - panic("kernel too big"); - mapfree(&rmapram, x, pa-x); - memset(KADDR(x), 0, pa-x); /* keep us honest */ -} - typedef struct Emap Emap; struct Emap { @@ -421,7 +402,7 @@ emapcmp(const void *va, const void *vb) static void map(uintptr base, uintptr len, int type) { - uintptr e, n, *pte, flags, maxkpa; + uintptr n, flags, maxkpa; /* * Split any call crossing MemMin to make below simpler. @@ -433,7 +414,7 @@ map(uintptr base, uintptr len, int type) } /* - * Let lowraminit and umbscan hash out the low MemMin. + * Let umbscan hash out the low MemMin. */ if(base < MemMin) return; @@ -497,21 +478,6 @@ map(uintptr base, uintptr len, int type) break; } - /* - * bottom MemMin is already mapped - just twiddle flags. - * (not currently used - see above) - */ - if(base < MemMin){ - e = base+len; - base &= ~((uintptr)PGLSZ(1)-1); - for(; basepml4, base+KZERO, 1, 0); - if(pte != 0 && *pte & PTEVALID) - *pte |= flags; - } - return; - } - if(flags){ maxkpa = -KZERO; if(base >= maxkpa) @@ -595,7 +561,6 @@ meminit(void) uintptr lost; umbscan(); - // lowraminit(); e820scan(); /* diff --git a/sys/src/9/pc64/mmu.c b/sys/src/9/pc64/mmu.c index c89dbf861..8081eb7d6 100644 --- a/sys/src/9/pc64/mmu.c +++ b/sys/src/9/pc64/mmu.c @@ -282,13 +282,13 @@ ptecount(uintptr va, int level) } void -pmap(uintptr *pml4, uintptr pa, uintptr va, int size) +pmap(uintptr *pml4, uintptr pa, uintptr va, vlong size) { uintptr *pte, *ptee, flags; int z, l; if((size <= 0) || va < VMAP) - panic("pmap: pa=%#p va=%#p size=%d", pa, va, size); + panic("pmap: pa=%#p va=%#p size=%lld", pa, va, size); flags = pa; pa = PPN(pa); flags -= pa; @@ -310,7 +310,7 @@ pmap(uintptr *pml4, uintptr pa, uintptr va, int size) size += z; continue; } - panic("pmap: pa=%#p va=%#p size=%d", pa, va, size); + panic("pmap: pa=%#p va=%#p size=%lld", pa, va, size); } ptee = pte + ptecount(va, l); while(size > 0 && pte < ptee){ diff --git a/sys/src/9/port/page.c b/sys/src/9/port/page.c index 96b7b9ab7..48e393d2b 100644 --- a/sys/src/9/port/page.c +++ b/sys/src/9/port/page.c @@ -16,16 +16,19 @@ pageinit(void) Page *p; Pallocmem *pm; vlong m, v, u; - ulong np; - np = 0; - for(i=0; inpage; + if(palloc.pages == nil){ + ulong np; + + np = 0; + for(i=0; inpage; + } + palloc.pages = xalloc(np*sizeof(Page)); + if(palloc.pages == nil) + panic("pageinit"); } - palloc.pages = xalloc(np*sizeof(Page)); - if(palloc.pages == 0) - panic("pageinit"); color = 0; palloc.head = palloc.pages; @@ -33,6 +36,7 @@ pageinit(void) for(i=0; inpage; j++){ + memset(p, 0, sizeof *p); p->prev = p-1; p->next = p+1; p->pa = pm->base+j*BY2PG;