kernel: get rid of physical page bank array and use conf.mem[] instead

We can take advantage of the fact that xinit() allocates
kernel memory from conf.mem[] banks always at the beginning
of a bank, so the separate palloc.mem[] array can be eleminated
as we can calculate the amount of non-kernel memory like:

upages = cm->npage - (PGROUND(cm->klimit - cm->kbase)/BY2PG)

for the number of reserved kernel pages,
we provide the new function: ulong nkpages(Confmem*)

This eleminates the error case of running out of slots in
the array and avoids wasting memory in ports that have simple
memory configurations (compared to pc/pc64).
This commit is contained in:
cinap_lenrek 2021-04-02 20:23:25 +02:00
parent c77b3ba143
commit 295acd7e0d
5 changed files with 45 additions and 53 deletions

View file

@ -652,16 +652,16 @@ patwc(void *a, int n)
void
preallocpages(void)
{
Pallocmem *pm;
Confmem *cm;
uintptr va, base, top;
vlong tsize, psize;
ulong np, nt;
int i;
np = 0;
for(i=0; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
np += pm->npage;
for(i=0; i<nelem(conf.mem); i++){
cm = &conf.mem[i];
np += cm->npage - nkpages(cm);
}
nt = np / 50; /* 2% for mmupool */
np -= nt;
@ -676,16 +676,19 @@ preallocpages(void)
psize += tsize;
psize = ROUND(psize, PGLSZ(1));
for(i=0; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
base = ROUND(pm->base, PGLSZ(1));
top = pm->base + (uvlong)pm->npage * BY2PG;
if((base + psize) <= VMAPSIZE && (vlong)(top - base) >= psize){
pm->base = base + psize;
pm->npage = (top - pm->base)/BY2PG;
for(i=0; i<nelem(conf.mem); i++){
cm = &conf.mem[i];
base = cm->base;
top = base + (uvlong)cm->npage * BY2PG;
base += (uvlong)nkpages(cm) * BY2PG;
top &= -PGLSZ(1);
if(top <= VMAPSIZE && (vlong)(top - base) >= psize){
/* steal memory from the end of the bank */
top -= psize;
cm->npage = (top - cm->base) / BY2PG;
va = base + VMAP;
pmap(base | PTEGLOBAL|PTEWRITE|PTENOEXEC|PTEVALID, va, psize);
va = top + VMAP;
pmap(top | PTEGLOBAL|PTEWRITE|PTENOEXEC|PTEVALID, va, psize);
palloc.pages = (void*)(va + tsize);

View file

@ -7,21 +7,27 @@
Palloc palloc;
ulong
nkpages(Confmem *cm)
{
return ((cm->klimit - cm->kbase) + BY2PG-1) / BY2PG;
}
void
pageinit(void)
{
int color, i, j;
Page *p, **t;
Pallocmem *pm;
Confmem *cm;
vlong m, v, u;
if(palloc.pages == nil){
ulong np;
np = 0;
for(i=0; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
np += pm->npage;
for(i=0; i<nelem(conf.mem); i++){
cm = &conf.mem[i];
np += cm->npage - nkpages(cm);
}
palloc.pages = xalloc(np*sizeof(Page));
if(palloc.pages == nil)
@ -35,11 +41,11 @@ pageinit(void)
t = &palloc.head;
p = palloc.pages;
for(i=0; i<nelem(palloc.mem); i++){
pm = &palloc.mem[i];
for(j=0; j<pm->npage; j++){
for(i=0; i<nelem(conf.mem); i++){
cm = &conf.mem[i];
for(j=nkpages(cm); j<cm->npage; j++){
memset(p, 0, sizeof *p);
p->pa = pm->base+j*BY2PG;
p->pa = cm->base+j*BY2PG;
if(cankaddr(p->pa) && (KADDR(p->pa) == nil || KADDR(p->pa) == (void*)-BY2PG))
continue;
p->color = color;

View file

@ -25,7 +25,6 @@ typedef struct Note Note;
typedef struct Page Page;
typedef struct Path Path;
typedef struct Palloc Palloc;
typedef struct Pallocmem Pallocmem;
typedef struct Perf Perf;
typedef struct PhysUart PhysUart;
typedef struct Pgrp Pgrp;
@ -519,12 +518,6 @@ enum
DELTAFD = 20 /* incremental increase in Fgrp.fd's */
};
struct Pallocmem
{
uintptr base;
ulong npage;
};
struct Palloc
{
Lock;
@ -533,7 +526,6 @@ struct Palloc
Page *pages; /* array of all pages */
ulong user; /* how many user pages */
Rendezq pwait[2]; /* Queues of procs waiting for memory */
Pallocmem mem[16]; /* physical user page banks */
};
struct Waitq

View file

@ -213,6 +213,7 @@ Rgrp* newrgrp(void);
Proc* newproc(void);
void nexterror(void);
int notify(Ureg*);
ulong nkpages(Confmem*);
uvlong ns2fastticks(uvlong);
int okaddr(uintptr, ulong, int);
int openmode(ulong);

View file

@ -43,10 +43,8 @@ void
xinit(void)
{
ulong maxpages, kpages, n;
uintptr size;
Confmem *m;
Pallocmem *pm;
Hole *h, *eh;
Confmem *cm;
int i;
eh = &xlists.hole[Nhole-1];
@ -57,36 +55,28 @@ xinit(void)
kpages = conf.npage - conf.upages;
pm = palloc.mem;
for(i=0; i<nelem(conf.mem); i++){
m = &conf.mem[i];
n = m->npage;
cm = &conf.mem[i];
n = cm->npage;
if(n > kpages)
n = kpages;
/* don't try to use non-KADDR-able memory for kernel */
maxpages = cankaddr(m->base)/BY2PG;
maxpages = cankaddr(cm->base)/BY2PG;
if(n > maxpages)
n = maxpages;
size = (uintptr)n*BY2PG;
/* first give to kernel */
/* give to kernel */
if(n > 0){
m->kbase = (uintptr)KADDR(m->base);
m->klimit = (uintptr)m->kbase+size;
if(m->klimit == 0)
m->klimit = (uintptr)-BY2PG;
xhole(m->base, m->klimit - m->kbase);
cm->kbase = (uintptr)KADDR(cm->base);
cm->klimit = (uintptr)cm->kbase+(uintptr)n*BY2PG;
if(cm->klimit == 0)
cm->klimit = (uintptr)-BY2PG;
xhole(cm->base, cm->klimit - cm->kbase);
kpages -= n;
}
/* if anything left over, give to user */
if(n < m->npage){
if(pm >= palloc.mem+nelem(palloc.mem)){
print("xinit: losing %lud pages\n", m->npage-n);
continue;
}
pm->base = m->base+size;
pm->npage = m->npage - n;
pm++;
}
/*
* anything left over: cm->npage - nkpages(cm)
* will be given to user by pageinit()
*/
}
xsummary();
}