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

View file

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

View file

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

View file

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

View file

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