FreeBSD/sys/arm/arm/pmap-v4.c
/*
 * Remove all pages from specified address space
 * this aids process exit speeds.  Also, this code
 * is special cased for current process only, but
 * can have the more generic (and slightly slower)
 * mode enabled.  This is much faster than pmap_remove
 * in the case of running down an entire address space.
 */
Remove all pages from specified address space
this aids process exit speeds.  Also, this code
is special cased for current process only, but
can have the more generic (and slightly slower)
mode enabled.  This is much faster than pmap_remove
in the case of running down an entire address space.
Remove all pages from specified address space this aids process exit speeds . Also this code is special cased for current process only but can have the more generic ( and slightly slower ) mode enabled . This is much faster than pmap_remove in the case of running down an entire address space .
void
pmap_remove_pages(pmap_t pmap)
{
	struct pv_entry *pv, *npv;
	struct l2_bucket *l2b = NULL;
	vm_page_t m;
	pt_entry_t *pt;
	rw_wlock(&pvh_global_lock);
	PMAP_LOCK(pmap);
	cpu_idcache_wbinv_all();
	cpu_l2cache_wbinv_all();
	for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) {
		if (pv->pv_flags & PVF_WIRED || pv->pv_flags & PVF_UNMAN) {
			npv = TAILQ_NEXT(pv, pv_plist);
			continue;
		}
		pmap->pm_stats.resident_count--;
		l2b = pmap_get_l2_bucket(pmap, pv->pv_va);
		KASSERT(l2b != NULL, ("No L2 bucket in pmap_remove_pages"));
		pt = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
		m = PHYS_TO_VM_PAGE(*pt & L2_S_FRAME);
		KASSERT((vm_offset_t)m >= KERNBASE, ("Trying to access non-existent page va %x pte %x", pv->pv_va, *pt));
		*pt = 0;
		PTE_SYNC(pt);
		npv = TAILQ_NEXT(pv, pv_plist);
		pmap_nuke_pv(m, pmap, pv);
		if (TAILQ_EMPTY(&m->md.pv_list))
			vm_page_aflag_clear(m, PGA_WRITEABLE);
		pmap_free_pv_entry(pv);
		pmap_free_l2_bucket(pmap, l2b, 1);
	}
	rw_wunlock(&pvh_global_lock);
	cpu_tlb_flushID();
	cpu_cpwait();
	PMAP_UNLOCK(pmap);
}
void pmap_remove_pages ( pmap_t pmap ) { struct pv_entry * pv , * npv ; struct l2_bucket * l2b = NULL ; vm_page_t m ; pt_entry_t * pt ; rw_wlock ( & pvh_global_lock ) ; PMAP_LOCK ( pmap ) ; cpu_idcache_wbinv_all ( ) ; cpu_l2cache_wbinv_all ( ) ; for ( pv = TAILQ_FIRST ( & pmap -> pm_pvlist ) ; pv ; pv = npv ) { if ( pv -> pv_flags & PVF_WIRED || pv -> pv_flags & PVF_UNMAN ) { npv = TAILQ_NEXT ( pv , pv_plist ) ; continue ; } pmap -> pm_stats . resident_count -- ; l2b = pmap_get_l2_bucket ( pmap , pv -> pv_va ) ; KASSERT ( l2b != NULL , ( " " ) ) ; pt = & l2b -> l2b_kva [ l2pte_index ( pv -> pv_va ) ] ; m = PHYS_TO_VM_PAGE ( * pt & L2_S_FRAME ) ; KASSERT ( ( vm_offset_t ) m >= KERNBASE , ( " " , pv -> pv_va , * pt ) ) ; * pt = 0 ; PTE_SYNC ( pt ) ; npv = TAILQ_NEXT ( pv , pv_plist ) ; pmap_nuke_pv ( m , pmap , pv ) ; if ( TAILQ_EMPTY ( & m -> md . pv_list ) ) vm_page_aflag_clear ( m , PGA_WRITEABLE ) ; pmap_free_pv_entry ( pv ) ; pmap_free_l2_bucket ( pmap , l2b , 1 ) ; } rw_wunlock ( & pvh_global_lock ) ; cpu_tlb_flushID ( ) ; cpu_cpwait ( ) ; PMAP_UNLOCK ( pmap ) ; }
Remove all pages from specified address space
 this aids process exit speeds.
Remove all pages from specified address space this aids process exit speeds .
/* Cannot remove wired or unmanaged pages now. */