Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_object.c
Show First 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mman.h> | #include <sys/mman.h> | ||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/pctrie.h> | #include <sys/pctrie.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/proc.h> /* for curproc, pageproc */ | #include <sys/proc.h> /* for curproc, pageproc */ | ||||
#include <sys/refcount.h> | |||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/resourcevar.h> | #include <sys/resourcevar.h> | ||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/user.h> | #include <sys/user.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#include <sys/vmmeter.h> | #include <sys/vmmeter.h> | ||||
#include <sys/sx.h> | #include <sys/sx.h> | ||||
▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | vm_object_zinit(void *mem, int size, int flags) | ||||
object = (vm_object_t)mem; | object = (vm_object_t)mem; | ||||
rw_init_flags(&object->lock, "vm object", RW_DUPOK | RW_NEW); | rw_init_flags(&object->lock, "vm object", RW_DUPOK | RW_NEW); | ||||
/* These are true for any object that has been freed */ | /* These are true for any object that has been freed */ | ||||
object->type = OBJT_DEAD; | object->type = OBJT_DEAD; | ||||
object->ref_count = 0; | object->ref_count = 0; | ||||
vm_radix_init(&object->rtree); | vm_radix_init(&object->rtree); | ||||
object->paging_in_progress = 0; | refcount_init(&object->paging_in_progress, 0); | ||||
object->resident_page_count = 0; | object->resident_page_count = 0; | ||||
object->shadow_count = 0; | object->shadow_count = 0; | ||||
object->flags = OBJ_DEAD; | object->flags = OBJ_DEAD; | ||||
mtx_lock(&vm_object_list_mtx); | mtx_lock(&vm_object_list_mtx); | ||||
TAILQ_INSERT_TAIL(&vm_object_list, object, object_list); | TAILQ_INSERT_TAIL(&vm_object_list, object, object_list); | ||||
mtx_unlock(&vm_object_list_mtx); | mtx_unlock(&vm_object_list_mtx); | ||||
return (0); | return (0); | ||||
▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | vm_object_set_memattr(vm_object_t object, vm_memattr_t memattr) | ||||
object->memattr = memattr; | object->memattr = memattr; | ||||
return (KERN_SUCCESS); | return (KERN_SUCCESS); | ||||
} | } | ||||
void | void | ||||
vm_object_pip_add(vm_object_t object, short i) | vm_object_pip_add(vm_object_t object, short i) | ||||
{ | { | ||||
VM_OBJECT_ASSERT_WLOCKED(object); | refcount_acquiren(&object->paging_in_progress, i); | ||||
object->paging_in_progress += i; | |||||
} | } | ||||
void | void | ||||
vm_object_pip_subtract(vm_object_t object, short i) | vm_object_pip_wakeup(vm_object_t object) | ||||
{ | { | ||||
VM_OBJECT_ASSERT_WLOCKED(object); | refcount_release(&object->paging_in_progress); | ||||
object->paging_in_progress -= i; | |||||
} | } | ||||
void | void | ||||
vm_object_pip_wakeup(vm_object_t object) | vm_object_pip_wakeupn(vm_object_t object, short i) | ||||
{ | { | ||||
VM_OBJECT_ASSERT_WLOCKED(object); | refcount_releasen(&object->paging_in_progress, i); | ||||
object->paging_in_progress--; | |||||
if ((object->flags & OBJ_PIPWNT) && object->paging_in_progress == 0) { | |||||
vm_object_clear_flag(object, OBJ_PIPWNT); | |||||
wakeup(object); | |||||
} | } | ||||
} | |||||
void | void | ||||
vm_object_pip_wakeupn(vm_object_t object, short i) | vm_object_pip_wait(vm_object_t object, char *waitid) | ||||
{ | { | ||||
VM_OBJECT_ASSERT_WLOCKED(object); | VM_OBJECT_ASSERT_WLOCKED(object); | ||||
if (i) | |||||
object->paging_in_progress -= i; | while (object->paging_in_progress) { | ||||
if ((object->flags & OBJ_PIPWNT) && object->paging_in_progress == 0) { | VM_OBJECT_WUNLOCK(object); | ||||
vm_object_clear_flag(object, OBJ_PIPWNT); | refcount_wait(&object->paging_in_progress, waitid, PVM); | ||||
wakeup(object); | VM_OBJECT_WLOCK(object); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
vm_object_pip_wait(vm_object_t object, char *waitid) | vm_object_pip_wait_unlocked(vm_object_t object, char *waitid) | ||||
{ | { | ||||
VM_OBJECT_ASSERT_WLOCKED(object); | VM_OBJECT_ASSERT_UNLOCKED(object); | ||||
while (object->paging_in_progress) { | |||||
object->flags |= OBJ_PIPWNT; | while (object->paging_in_progress) | ||||
VM_OBJECT_SLEEP(object, object, PVM, waitid, 0); | refcount_wait(&object->paging_in_progress, waitid, PVM); | ||||
} | } | ||||
} | |||||
/* | /* | ||||
* vm_object_allocate: | * vm_object_allocate: | ||||
* | * | ||||
* Returns a new object with the given size. | * Returns a new object with the given size. | ||||
*/ | */ | ||||
vm_object_t | vm_object_t | ||||
vm_object_allocate(objtype_t type, vm_pindex_t size) | vm_object_allocate(objtype_t type, vm_pindex_t size) | ||||
▲ Show 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | retry: | ||||
"objde1"); | "objde1"); | ||||
temp = robject->backing_object; | temp = robject->backing_object; | ||||
if (object == temp) { | if (object == temp) { | ||||
VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
goto retry; | goto retry; | ||||
} | } | ||||
} else if (object->paging_in_progress) { | } else if (object->paging_in_progress) { | ||||
VM_OBJECT_WUNLOCK(robject); | VM_OBJECT_WUNLOCK(robject); | ||||
object->flags |= OBJ_PIPWNT; | VM_OBJECT_WUNLOCK(object); | ||||
VM_OBJECT_SLEEP(object, object, | refcount_wait( | ||||
PDROP | PVM, "objde2", 0); | &object->paging_in_progress, | ||||
"objde2", PVM); | |||||
VM_OBJECT_WLOCK(robject); | VM_OBJECT_WLOCK(robject); | ||||
temp = robject->backing_object; | temp = robject->backing_object; | ||||
if (object == temp) { | if (object == temp) { | ||||
VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
goto retry; | goto retry; | ||||
} | } | ||||
} else | } else | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
▲ Show 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | vm_object_terminate(vm_object_t object) | ||||
VM_OBJECT_ASSERT_WLOCKED(object); | VM_OBJECT_ASSERT_WLOCKED(object); | ||||
/* | /* | ||||
* Make sure no one uses us. | * Make sure no one uses us. | ||||
*/ | */ | ||||
vm_object_set_flag(object, OBJ_DEAD); | vm_object_set_flag(object, OBJ_DEAD); | ||||
/* | /* | ||||
* wait for the pageout daemon to be done with the object | |||||
*/ | |||||
vm_object_pip_wait(object, "objtrm"); | |||||
KASSERT(!object->paging_in_progress, | |||||
("vm_object_terminate: pageout in progress")); | |||||
/* | |||||
* Clean and free the pages, as appropriate. All references to the | * Clean and free the pages, as appropriate. All references to the | ||||
* object are gone, so we don't need to lock it. | * object are gone, so we don't need to lock it. | ||||
*/ | */ | ||||
if (object->type == OBJT_VNODE) { | if (object->type == OBJT_VNODE) { | ||||
struct vnode *vp = (struct vnode *)object->handle; | struct vnode *vp = (struct vnode *)object->handle; | ||||
/* | /* | ||||
* Clean pages and flush buffers. | * Clean pages and flush buffers. | ||||
*/ | */ | ||||
vm_object_page_clean(object, 0, 0, OBJPC_SYNC); | vm_object_page_clean(object, 0, 0, OBJPC_SYNC); | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
vinvalbuf(vp, V_SAVE, 0, 0); | vinvalbuf(vp, V_SAVE, 0, 0); | ||||
BO_LOCK(&vp->v_bufobj); | BO_LOCK(&vp->v_bufobj); | ||||
vp->v_bufobj.bo_flag |= BO_DEAD; | vp->v_bufobj.bo_flag |= BO_DEAD; | ||||
BO_UNLOCK(&vp->v_bufobj); | BO_UNLOCK(&vp->v_bufobj); | ||||
VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
} | } | ||||
/* | |||||
* wait for the pageout daemon to be done with the object | |||||
*/ | |||||
vm_object_pip_wait(object, "objtrm"); | |||||
KASSERT(!object->paging_in_progress, | |||||
("vm_object_terminate: pageout in progress")); | |||||
KASSERT(object->ref_count == 0, | KASSERT(object->ref_count == 0, | ||||
("vm_object_terminate: object with references, ref_count=%d", | ("vm_object_terminate: object with references, ref_count=%d", | ||||
object->ref_count)); | object->ref_count)); | ||||
if ((object->flags & OBJ_PG_DTOR) == 0) | if ((object->flags & OBJ_PG_DTOR) == 0) | ||||
vm_object_terminate_pages(object); | vm_object_terminate_pages(object); | ||||
▲ Show 20 Lines • Show All 1,888 Lines • Show Last 20 Lines |