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.
This commit is contained in:
cinap_lenrek 2014-06-01 03:13:58 +02:00
parent 8061f30e55
commit c9f91d5015
6 changed files with 59 additions and 52 deletions

View file

@ -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*);

View file

@ -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; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
np += pm->npage;
}
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; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
if((pm->base + 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();

View file

@ -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)

View file

@ -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(; base<e; base+=PGLSZ(1)){
pte = mmuwalk(m->pml4, 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();
/*

View file

@ -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){

View file

@ -16,16 +16,19 @@ pageinit(void)
Page *p;
Pallocmem *pm;
vlong m, v, u;
ulong np;
np = 0;
for(i=0; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
np += pm->npage;
if(palloc.pages == nil){
ulong np;
np = 0;
for(i=0; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
np += pm->npage;
}
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; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
for(j=0; j<pm->npage; j++){
memset(p, 0, sizeof *p);
p->prev = p-1;
p->next = p+1;
p->pa = pm->base+j*BY2PG;