/* * lpage_destroy: deallocates a logical page. Releases any RAM or swap * pages involved. * * Synchronization: Someone might be in the process of evicting the * page if it's resident, so it might be pinned. So lock and pin * together. * * We assume that lpages are not shared between address spaces and * address spaces are not shared between threads. */ void lpage_destroy(struct lpage *lp) { paddr_t pa; KASSERT(lp != NULL); lpage_lock_and_pin(lp); pa = lp->lp_paddr & PAGE_FRAME; if (pa != INVALID_PADDR) { DEBUG(DB_VM, "lpage_destroy: freeing paddr 0x%x\n", pa); lp->lp_paddr = INVALID_PADDR; lpage_unlock(lp); coremap_free(pa, false /* iskern */); coremap_unpin(pa); } else { lpage_unlock(lp); } if (lp->lp_swapaddr != INVALID_SWAPADDR) { DEBUG(DB_VM, "lpage_destroy: freeing swap addr 0x%llx\n", lp->lp_swapaddr); swap_free(lp->lp_swapaddr); } spinlock_cleanup(&lp->lp_spinlock); kfree(lp); }
void free_kpages(vaddr_t addr) { paddr_t pa = KVADDR_TO_PADDR(addr); if (pa < start_addr) (void)addr; // dont do anything // we have no access to these memory else coremap_free(pa); }
static void coremapthread(void *sm, unsigned long num) { struct semaphore *sem = sm; uint32_t page; uint32_t oldpage = 0; uint32_t oldpage2 = 0; int i; for (i=0; i<NTRIES; i++) { page = alloc_kpages(NPAGES); if (page==0) { if (sem) { kprintf("thread %lu: alloc_kpages failed\n", num); V(sem); return; } kprintf("alloc_kpages failed; test failed.\n"); return; } if (oldpage2) { coremap_free(KVADDR_TO_PADDR(oldpage2), true /* iskern */); } oldpage2 = oldpage; oldpage = page; } if (oldpage2) { coremap_free(KVADDR_TO_PADDR(oldpage2), true /* iskern */); } if (oldpage) { coremap_free(KVADDR_TO_PADDR(oldpage), true /* iskern */); } if (sem) { V(sem); } }
/* * free_kpages * * Free pages allocated with alloc_kpages. * Synchronization: takes coremap_spinlock. Does not block. */ void free_kpages(vaddr_t addr) { coremap_free(KVADDR_TO_PADDR(addr), true /* iskern */); }