FreeBSD/sys/arm64/arm64/pmap.c
/*
 * free the pv_entry back to the free list
 */
free the pv_entry back to the free list
free the pv_entry back to the free list
static void
free_pv_entry(pmap_t pmap, pv_entry_t pv)
{
	struct pv_chunk *pc;
	int idx, field, bit;
	rw_assert(&pvh_global_lock, RA_LOCKED);
	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
	PV_STAT(atomic_add_long(&pv_entry_frees, 1));
	PV_STAT(atomic_add_int(&pv_entry_spare, 1));
	PV_STAT(atomic_subtract_long(&pv_entry_count, 1));
	pc = pv_to_chunk(pv);
	idx = pv - &pc->pc_pventry[0];
	field = idx / 64;
	bit = idx % 64;
	pc->pc_map[field] |= 1ul << bit;
	if (pc->pc_map[0] != PC_FREE0 || pc->pc_map[1] != PC_FREE1 ||
	    pc->pc_map[2] != PC_FREE2) {
		if (__predict_false(pc != TAILQ_FIRST(&pmap->pm_pvchunk))) {
			TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
			TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list);
		}
		return;
	}
	TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
	free_pv_chunk(pc);
}
static void free_pv_entry ( pmap_t pmap , pv_entry_t pv ) { struct pv_chunk * pc ; int idx , field , bit ; rw_assert ( & pvh_global_lock , RA_LOCKED ) ; PMAP_LOCK_ASSERT ( pmap , MA_OWNED ) ; PV_STAT ( atomic_add_long ( & pv_entry_frees , 1 ) ) ; PV_STAT ( atomic_add_int ( & pv_entry_spare , 1 ) ) ; PV_STAT ( atomic_subtract_long ( & pv_entry_count , 1 ) ) ; pc = pv_to_chunk ( pv ) ; idx = pv - & pc -> pc_pventry [ 0 ] ; field = idx / 64 ; bit = idx % 64 ; pc -> pc_map [ field ] |= 1ul << bit ; if ( pc -> pc_map [ 0 ] != PC_FREE0 || pc -> pc_map [ 1 ] != PC_FREE1 || pc -> pc_map [ 2 ] != PC_FREE2 ) { if ( __predict_false ( pc != TAILQ_FIRST ( & pmap -> pm_pvchunk ) ) ) { TAILQ_REMOVE ( & pmap -> pm_pvchunk , pc , pc_list ) ; TAILQ_INSERT_HEAD ( & pmap -> pm_pvchunk , pc , pc_list ) ; } return ; } TAILQ_REMOVE ( & pmap -> pm_pvchunk , pc , pc_list ) ; free_pv_chunk ( pc ) ; }
free the pv_entry back to the free list
free the pv_entry back to the free list
/* 98% of the time, pc is already at the head of the list. */