FreeBSD/sys/arm/arm/pmap-v6.c
/*
 *	Routine:	pmap_remove_all
 *	Function:
 *		Removes this physical page from
 *		all physical maps in which it resides.
 *		Reflects back modify bits to the pager.
 *
 *	Notes:
 *		Original versions of this routine were very
 *		inefficient because they iteratively called
 *		pmap_remove (slow...)
 */
pmap_remove_all
Function:
Removes this physical page from
all physical maps in which it resides.
Reflects back modify bits to the pager.

Original versions of this routine were very
inefficient because they iteratively called
pmap_remove (slow...)
pmap_remove_all Function : Removes this physical page from all physical maps in which it resides . Reflects back modify bits to the pager . Original versions of this routine were very inefficient because they iteratively called pmap_remove ( slow ... )
void
pmap_remove_all(vm_page_t m)
{
	struct md_page *pvh;
	pv_entry_t pv;
	pmap_t pmap;
	pt2_entry_t *pte2p, opte2;
	pt1_entry_t *pte1p;
	vm_offset_t va;
	struct spglist free;
	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
	    ("%s: page %p is not managed", __func__, m));
	SLIST_INIT(&free);
	rw_wlock(&pvh_global_lock);
	sched_pin();
	if ((m->flags & PG_FICTITIOUS) != 0)
		goto small_mappings;
	pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
	while ((pv = TAILQ_FIRST(&pvh->pv_list)) != NULL) {
		va = pv->pv_va;
		pmap = PV_PMAP(pv);
		PMAP_LOCK(pmap);
		pte1p = pmap_pte1(pmap, va);
		(void)pmap_demote_pte1(pmap, pte1p, va);
		PMAP_UNLOCK(pmap);
	}
small_mappings:
	while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
		pmap = PV_PMAP(pv);
		PMAP_LOCK(pmap);
		pmap->pm_stats.resident_count--;
		pte1p = pmap_pte1(pmap, pv->pv_va);
		KASSERT(!pte1_is_section(pte1_load(pte1p)), ("%s: found "
		    "a 1mpage in page %p's pv list", __func__, m));
		pte2p = pmap_pte2_quick(pmap, pv->pv_va);
		opte2 = pte2_load_clear(pte2p);
		pmap_tlb_flush(pmap, pv->pv_va);
		KASSERT(pte2_is_valid(opte2), ("%s: pmap %p va %x zero pte2",
		    __func__, pmap, pv->pv_va));
		if (pte2_is_wired(opte2))
			pmap->pm_stats.wired_count--;
		if (opte2 & PTE2_A)
			vm_page_aflag_set(m, PGA_REFERENCED);
		if (pte2_is_dirty(opte2))
			vm_page_dirty(m);
		pmap_unuse_pt2(pmap, pv->pv_va, &free);
		TAILQ_REMOVE(&m->md.pv_list, pv, pv_next);
		free_pv_entry(pmap, pv);
		PMAP_UNLOCK(pmap);
	}
	vm_page_aflag_clear(m, PGA_WRITEABLE);
	sched_unpin();
	rw_wunlock(&pvh_global_lock);
	pmap_free_zero_pages(&free);
}
void pmap_remove_all ( vm_page_t m ) { struct md_page * pvh ; pv_entry_t pv ; pmap_t pmap ; pt2_entry_t * pte2p , opte2 ; pt1_entry_t * pte1p ; vm_offset_t va ; struct spglist free ; KASSERT ( ( m -> oflags & VPO_UNMANAGED ) == 0 , ( " " , __func__ , m ) ) ; SLIST_INIT ( & free ) ; rw_wlock ( & pvh_global_lock ) ; sched_pin ( ) ; if ( ( m -> flags & PG_FICTITIOUS ) != 0 ) goto small_mappings ; pvh = pa_to_pvh ( VM_PAGE_TO_PHYS ( m ) ) ; while ( ( pv = TAILQ_FIRST ( & pvh -> pv_list ) ) != NULL ) { va = pv -> pv_va ; pmap = PV_PMAP ( pv ) ; PMAP_LOCK ( pmap ) ; pte1p = pmap_pte1 ( pmap , va ) ; ( void ) pmap_demote_pte1 ( pmap , pte1p , va ) ; PMAP_UNLOCK ( pmap ) ; } small_mappings : while ( ( pv = TAILQ_FIRST ( & m -> md . pv_list ) ) != NULL ) { pmap = PV_PMAP ( pv ) ; PMAP_LOCK ( pmap ) ; pmap -> pm_stats . resident_count -- ; pte1p = pmap_pte1 ( pmap , pv -> pv_va ) ; KASSERT ( ! pte1_is_section ( pte1_load ( pte1p ) ) , ( " " " " , __func__ , m ) ) ; pte2p = pmap_pte2_quick ( pmap , pv -> pv_va ) ; opte2 = pte2_load_clear ( pte2p ) ; pmap_tlb_flush ( pmap , pv -> pv_va ) ; KASSERT ( pte2_is_valid ( opte2 ) , ( " " , __func__ , pmap , pv -> pv_va ) ) ; if ( pte2_is_wired ( opte2 ) ) pmap -> pm_stats . wired_count -- ; if ( opte2 & PTE2_A ) vm_page_aflag_set ( m , PGA_REFERENCED ) ; if ( pte2_is_dirty ( opte2 ) ) vm_page_dirty ( m ) ; pmap_unuse_pt2 ( pmap , pv -> pv_va , & free ) ; TAILQ_REMOVE ( & m -> md . pv_list , pv , pv_next ) ; free_pv_entry ( pmap , pv ) ; PMAP_UNLOCK ( pmap ) ; } vm_page_aflag_clear ( m , PGA_WRITEABLE ) ; sched_unpin ( ) ; rw_wunlock ( & pvh_global_lock ) ; pmap_free_zero_pages ( & free ) ; }
Routine:        pmap_remove_all
      Function:
              Removes this physical page from
              all physical maps in which it resides.
Routine : pmap_remove_all Function : Removes this physical page from all physical maps in which it resides .
/*
		 * Update the vm_page_t clean and reference bits.
		 */