void pgt_flush_ctx_range(struct pgt_cache *pgt_cache, void *ctx, vaddr_t begin, vaddr_t last) { mutex_lock(&pgt_mu); flush_ctx_range_from_list(pgt_cache, ctx, begin, last); flush_ctx_range_from_list(&pgt_cache_list, ctx, begin, last); condvar_broadcast(&pgt_cv); mutex_unlock(&pgt_mu); }
/** Free frames of physical memory. * * Find respective frame structures for supplied physical frames. * Decrement each frame reference count. If it drops to zero, mark * the frames as available. * * @param start Physical Address of the first frame to be freed. * @param count Number of frames to free. * @param flags Flags to control memory reservation. * */ void frame_free_generic(uintptr_t start, size_t count, frame_flags_t flags) { size_t freed = 0; irq_spinlock_lock(&zones.lock, true); for (size_t i = 0; i < count; i++) { /* * First, find host frame zone for addr. */ pfn_t pfn = ADDR2PFN(start) + i; size_t znum = find_zone(pfn, 1, 0); ASSERT(znum != (size_t) -1); freed += zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base); } irq_spinlock_unlock(&zones.lock, true); /* * Signal that some memory has been freed. * Since the mem_avail_mtx is an active mutex, * we need to disable interruptsto prevent deadlock * with TLB shootdown. */ ipl_t ipl = interrupts_disable(); mutex_lock(&mem_avail_mtx); if (mem_avail_req > 0) mem_avail_req -= min(mem_avail_req, freed); if (mem_avail_req == 0) { mem_avail_gen++; condvar_broadcast(&mem_avail_cv); } mutex_unlock(&mem_avail_mtx); interrupts_restore(ipl); if (!(flags & FRAME_NO_RESERVE)) reserve_free(freed); }