Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_sendfile.c
Show First 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Detach mapped page and release resources back to the system. Called | * Detach mapped page and release resources back to the system. Called | ||||
* by mbuf(9) code when last reference to a page is freed. | * by mbuf(9) code when last reference to a page is freed. | ||||
*/ | */ | ||||
static void | static void | ||||
sendfile_free_page(vm_page_t pg, bool nocache) | sendfile_free_page(vm_page_t pg, bool nocache) | ||||
{ | { | ||||
bool freed; | |||||
vm_page_lock(pg); | vm_page_lock(pg); | ||||
/* | /* | ||||
* In either case check for the object going away on us. This can | * In either case check for the object going away on us. This can | ||||
* happen since we don't hold a reference to it. If so, we're | * happen since we don't hold a reference to it. If so, we're | ||||
* responsible for freeing the page. In 'noncache' case try to free | * responsible for freeing the page. In 'noncache' case try to free | ||||
* the page, but only if it is cheap to. | * the page, but only if it is cheap to. | ||||
*/ | */ | ||||
if (vm_page_unwire(pg, nocache ? PQ_NONE : PQ_INACTIVE)) { | if (vm_page_unwire_noq(pg)) { | ||||
vm_object_t obj; | vm_object_t obj; | ||||
if ((obj = pg->object) == NULL) | if ((obj = pg->object) == NULL) | ||||
vm_page_free(pg); | vm_page_free(pg); | ||||
else if (nocache) { | else { | ||||
if (!vm_page_xbusied(pg) && VM_OBJECT_TRYWLOCK(obj)) { | freed = false; | ||||
bool freed; | if (nocache && !vm_page_xbusied(pg) && | ||||
VM_OBJECT_TRYWLOCK(obj)) { | |||||
/* Only free unmapped pages. */ | /* Only free unmapped pages. */ | ||||
if (obj->ref_count == 0 || | if (obj->ref_count == 0 || | ||||
!pmap_page_is_mapped(pg)) | !pmap_page_is_mapped(pg)) | ||||
/* | /* | ||||
* The busy test before the object is | * The busy test before the object is | ||||
* locked cannot be relied upon. | * locked cannot be relied upon. | ||||
*/ | */ | ||||
freed = vm_page_try_to_free(pg); | freed = vm_page_try_to_free(pg); | ||||
else | |||||
freed = false; | |||||
VM_OBJECT_WUNLOCK(obj); | VM_OBJECT_WUNLOCK(obj); | ||||
if (!freed) | } | ||||
if (!freed) { | |||||
/* | |||||
* If we were asked to not cache the page, place | |||||
* it near the head of the inactive queue so | |||||
* that it is reclaimed sooner. Otherwise, | |||||
* maintain LRU. | |||||
*/ | |||||
if (nocache) | |||||
vm_page_deactivate_noreuse(pg); | vm_page_deactivate_noreuse(pg); | ||||
} else | else if (pg->queue == PQ_ACTIVE) | ||||
vm_page_deactivate_noreuse(pg); | vm_page_reference(pg); | ||||
else if (pg->queue != PQ_INACTIVE) | |||||
vm_page_deactivate(pg); | |||||
else | |||||
vm_page_requeue(pg); | |||||
} | |||||
} | } | ||||
} | } | ||||
vm_page_unlock(pg); | vm_page_unlock(pg); | ||||
} | } | ||||
static void | static void | ||||
sendfile_free_mext(struct mbuf *m) | sendfile_free_mext(struct mbuf *m) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 877 Lines • Show Last 20 Lines |