FreeBSD/sys/x86/iommu/intel_idpgtbl.c
/*
 * Return a reference to the identity mapping page table to the cache.
 */
Return a reference to the identity mapping page table to the cache.
Return a reference to the identity mapping page table to the cache .
void
put_idmap_pgtbl(vm_object_t obj)
{
	struct idpgtbl *tbl, *tbl1;
	vm_object_t rmobj;
	sx_slock(&idpgtbl_lock);
	KASSERT(obj->ref_count >= 2, ("lost cache reference"));
	vm_object_deallocate(obj);
	if (obj->ref_count > 1) {
		sx_sunlock(&idpgtbl_lock);
		return;
	}
	sx_sunlock(&idpgtbl_lock);
	sx_xlock(&idpgtbl_lock);
	LIST_FOREACH_SAFE(tbl, &idpgtbls, link, tbl1) {
		rmobj = tbl->pgtbl_obj;
		if (rmobj->ref_count == 1) {
			LIST_REMOVE(tbl, link);
			atomic_subtract_int(&dmar_tbl_pagecnt,
			    rmobj->resident_page_count);
			vm_object_deallocate(rmobj);
			free(tbl, M_DMAR_IDPGTBL);
		}
	}
	sx_xunlock(&idpgtbl_lock);
}
void put_idmap_pgtbl ( vm_object_t obj ) { struct idpgtbl * tbl , * tbl1 ; vm_object_t rmobj ; sx_slock ( & idpgtbl_lock ) ; KASSERT ( obj -> ref_count >= 2 , ( " " ) ) ; vm_object_deallocate ( obj ) ; if ( obj -> ref_count > 1 ) { sx_sunlock ( & idpgtbl_lock ) ; return ; } sx_sunlock ( & idpgtbl_lock ) ; sx_xlock ( & idpgtbl_lock ) ; LIST_FOREACH_SAFE ( tbl , & idpgtbls , link , tbl1 ) { rmobj = tbl -> pgtbl_obj ; if ( rmobj -> ref_count == 1 ) { LIST_REMOVE ( tbl , link ) ; atomic_subtract_int ( & dmar_tbl_pagecnt , rmobj -> resident_page_count ) ; vm_object_deallocate ( rmobj ) ; free ( tbl , M_DMAR_IDPGTBL ) ; } } sx_xunlock ( & idpgtbl_lock ) ; }
Return a reference to the identity mapping page table to the cache.
Return a reference to the identity mapping page table to the cache .
/*
	 * Cache always owns one last reference on the page table object.
	 * If there is an additional reference, object must stay.
	 */ /*
	 * Cache reference is the last, remove cache element and free
	 * page table object, returning the page table pages to the
	 * system.
	 */