FreeBSD/sys/arm/arm/pmap-v4.c
/*
 * One or more mappings in the specified L2 descriptor table have just been
 * invalidated.
 *
 * Garbage collect the metadata and descriptor table itself if necessary.
 *
 * The pmap lock must be acquired when this is called (not necessary
 * for the kernel pmap).
 */
One or more mappings in the specified L2 descriptor table have just been
invalidated.

Garbage collect the metadata and descriptor table itself if necessary.

The pmap lock must be acquired when this is called (not necessary
for the kernel pmap).
One or more mappings in the specified L2 descriptor table have just been invalidated . Garbage collect the metadata and descriptor table itself if necessary . The pmap lock must be acquired when this is called ( not necessary for the kernel pmap ) .
static void
pmap_free_l2_bucket(pmap_t pm, struct l2_bucket *l2b, u_int count)
{
	struct l2_dtable *l2;
	pd_entry_t *pl1pd, l1pd;
	pt_entry_t *ptep;
	u_short l1idx;
	l2b->l2b_occupancy -= count;
	if (l2b->l2b_occupancy > 0 || pm == kernel_pmap)
		return;
	l1idx = l2b->l2b_l1idx;
	ptep = l2b->l2b_kva;
	l2b->l2b_kva = NULL;
	pl1pd = &pm->pm_l1->l1_kva[l1idx];
	l1pd = *pl1pd & (L1_TYPE_MASK | L1_C_DOM_MASK);
	if (l1pd == (L1_C_DOM(pm->pm_domain) | L1_TYPE_C)) {
		*pl1pd = 0;
		PTE_SYNC(pl1pd);
	}
#ifndef PMAP_INCLUDE_PTE_SYNC
	pmap_free_l2_ptp(ptep);
#else
	pmap_free_l2_ptp(!pmap_is_current(pm), ptep);
#endif
	l2 = pm->pm_l2[L2_IDX(l1idx)];
	if (--l2->l2_occupancy > 0)
		return;
	pm->pm_l2[L2_IDX(l1idx)] = NULL;
	uma_zfree(l2table_zone, l2);
}
static void pmap_free_l2_bucket ( pmap_t pm , struct l2_bucket * l2b , u_int count ) { struct l2_dtable * l2 ; pd_entry_t * pl1pd , l1pd ; pt_entry_t * ptep ; u_short l1idx ; l2b -> l2b_occupancy -= count ; if ( l2b -> l2b_occupancy > 0 || pm == kernel_pmap ) return ; l1idx = l2b -> l2b_l1idx ; ptep = l2b -> l2b_kva ; l2b -> l2b_kva = NULL ; pl1pd = & pm -> pm_l1 -> l1_kva [ l1idx ] ; l1pd = * pl1pd & ( L1_TYPE_MASK | L1_C_DOM_MASK ) ; if ( l1pd == ( L1_C_DOM ( pm -> pm_domain ) | L1_TYPE_C ) ) { * pl1pd = 0 ; PTE_SYNC ( pl1pd ) ; } #ifndef PMAP_INCLUDE_PTE_SYNC pmap_free_l2_ptp ( ptep ) ; #else pmap_free_l2_ptp ( ! pmap_is_current ( pm ) , ptep ) ; #endif l2 = pm -> pm_l2 [ L2_IDX ( l1idx ) ] ; if ( -- l2 -> l2_occupancy > 0 ) return ; pm -> pm_l2 [ L2_IDX ( l1idx ) ] = NULL ; uma_zfree ( l2table_zone , l2 ) ; }
One or more mappings in the specified L2 descriptor table have just been
 invalidated.
One or more mappings in the specified L2 descriptor table have just been invalidated .
/*
	 * Update the bucket's reference count according to how many
	 * PTEs the caller has just invalidated.
	 */ /*
	 * Note:
	 *
	 * Level 2 page tables allocated to the kernel pmap are never freed
	 * as that would require checking all Level 1 page tables and
	 * removing any references to the Level 2 page table. See also the
	 * comment elsewhere about never freeing bootstrap L2 descriptors.
	 *
	 * We make do with just invalidating the mapping in the L2 table.
	 *
	 * This isn't really a big deal in practice and, in fact, leads
	 * to a performance win over time as we don't need to continually
	 * alloc/free.
	 */ /*
	 * There are no more valid mappings in this level 2 page table.
	 * Go ahead and NULL-out the pointer in the bucket, then
	 * free the page table.
	 */ /*
	 * If the L1 slot matches the pmap's domain
	 * number, then invalidate it.
	 */ /*
	 * Release the L2 descriptor table back to the pool cache.
	 */ /*
	 * Update the reference count in the associated l2_dtable
	 */ /*
	 * There are no more valid mappings in any of the Level 1
	 * slots managed by this l2_dtable. Go ahead and NULL-out
	 * the pointer in the parent pmap and free the l2_dtable.
	 */