void xinit(void) { int i, n, upages, kpages; ulong maxpages; Confmem *m; Pallocmem *pm; Hole *h, *eh; eh = &xlists.hole[Nhole-1]; for(h = xlists.hole; h < eh; h++) h->link = h+1; xlists.flist = xlists.hole; upages = conf.upages; kpages = conf.npage - upages; pm = palloc.mem; for(i=0; i<nelem(conf.mem); i++){ m = &conf.mem[i]; n = m->npage; if(n > kpages) n = kpages; /* don't try to use non-KADDR-able memory for kernel */ maxpages = cankaddr(m->base)/BY2PG; if(n > maxpages) n = maxpages; /* first give to kernel */ if(n > 0){ m->kbase = (ulong)KADDR(m->base); m->klimit = (ulong)KADDR(m->base+n*BY2PG); xhole(m->base, n*BY2PG); 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+n*BY2PG; pm->npage = m->npage - n; pm++; } } xsummary(); }
KMap* kmap(Page *page) { uintptr *pte, pa, va; int x; pa = page->pa; if(cankaddr(pa) != 0) return (KMap*)KADDR(pa); x = splhi(); va = KMAP + ((uintptr)up->kmapindex << PGSHIFT); pte = mmuwalk(m->pml4, va, 0, 1); if(pte == 0 || *pte & PTEVALID) panic("kmap: pa=%#p va=%#p", pa, va); *pte = pa | PTEWRITE|PTEVALID; up->kmapindex = (up->kmapindex + 1) % (1<<PTSHIFT); if(up->kmapindex == 0) mmuflushtlb(); splx(x); return (KMap*)va; }
void confinit(void) { char *p; int i, userpcnt; unsigned mb; ulong kpages, ksize; if(p = getconf("*kernelpercent")) userpcnt = 100 - strtol(p, 0, 0); else userpcnt = 0; conf.npage = 0; for(i=0; i<nelem(conf.mem); i++) conf.npage += conf.mem[i].npage; conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5; if(cpuserver) conf.nproc *= 3; if(conf.nproc > 2000) conf.nproc = 2000; conf.nimage = 200; conf.nswap = conf.nproc*80; conf.nswppo = 4096; if(cpuserver) { if(userpcnt < 10) userpcnt = 70; kpages = conf.npage - (conf.npage*userpcnt)/100; /* * Hack for the big boys. Only good while physmem < 4GB. * Give the kernel fixed max + enough to allocate the * page pool. * This is an overestimate as conf.upages < conf.npages. * The patch of nimage is a band-aid, scanning the whole * page list in imagereclaim just takes too long. */ for (mb = 400; mb >= 100; mb /= 2) { ksize = mb*MB + conf.npage*sizeof(Page); if(kpages > ksize/BY2PG && cankaddr(ksize)) { kpages = ksize/BY2PG + (conf.nproc*KSTACK)/BY2PG; conf.nimage = 2000; break; } } } else { if(userpcnt < 10) { if(conf.npage*BY2PG < 16*MB) userpcnt = 40; else userpcnt = 60; } kpages = conf.npage - (conf.npage*userpcnt)/100; /* * Make sure terminals with low memory get at least * 4MB on the first Image chunk allocation. */ if(conf.npage*BY2PG < 16*MB) imagmem->minarena = 4*1024*1024; } /* * can't go past the end of virtual memory * (ulong)-KZERO is 2^32 - KZERO */ if(kpages > ((ulong)-KZERO)/BY2PG) kpages = ((ulong)-KZERO)/BY2PG; conf.upages = conf.npage - kpages; conf.ialloc = (kpages/2)*BY2PG; /* * Guess how much is taken by the large permanent * datastructures. Mntcache and Mntrpc are not accounted for * (probably ~300KB). */ kpages *= BY2PG; kpages -= conf.upages*sizeof(Page) + conf.nproc*sizeof(Proc) + conf.nimage*sizeof(Image) + conf.nswap + conf.nswppo*sizeof(Page); mainmem->maxsize = kpages; if(!cpuserver){ /* * give terminals lots of image memory, too; the dynamic * allocation will balance the load properly, hopefully. * be careful with 32-bit overflow. */ imagmem->maxsize = kpages; } }