static void freepages(int si, int once) { Proc *up = externup(); Pgsza *pa; Page *p; for(; si < sys->npgsz; si++){ pa = &pga.pgsza[si]; if(pa->freecount > 0){ DBG("kickpager() up %#p: releasing %udK pages\n", up, sys->pgsz[si]/KiB); lock(&pga); if(pa->freecount == 0){ unlock(&pga); continue; } p = pa->head; pageunchain(p); unlock(&pga); if(p->ref != 0) panic("freepages pa %#ullx", p->pa); pgfree(p); if(once) break; } } }
/* decrease all the pages' reference count, and free the page tables. */ int pt_free(struct pde *pgd){ struct pde *pde; struct pte *pte, *pt; struct page *pg; uint pdn, pn; for(pdn=PDX(KMEM_END); pdn<1024; pdn++) { pde = &pgd[pdn]; if (pde->pd_flag & PTE_P) { pt = (struct pte*)(pde->pd_off * PAGE); for(pn=0; pn<1024; pn++) { pte = &pt[pn]; if (pte->pt_flag & PTE_P) { pg = pgfind(pte->pt_off); pgfree(pg); } } kfree(pt, PAGE); } } return 0; }
void putpage(Page *p) { Pgsza *pa; int rlse; lock(&pga.l); lock(&p->l); if(p->ref == 0) panic("putpage"); if(--p->ref > 0) { unlock(&p->l); unlock(&pga.l); return; } rlse = 0; if(p->image != nil) pagechaintail(p); else{ /* * Free pages if we have plenty in the free list. */ pa = &pga.pgsza[p->pgszi]; if(pa->freecount > Nfreepgs) rlse = 1; else pagechainhead(p); } if(pga.rend.l.p != nil) wakeup(&pga.rend); unlock(&p->l); if(rlse) pgfree(p); unlock(&pga.l); }