Changeset View
Standalone View
sys/vm/vm_object.c
Show First 20 Lines • Show All 487 Lines • ▼ Show 20 Lines | if (object->ref_count == 0) { | ||||
vn_printf(vp, "vm_object_vndeallocate "); | vn_printf(vp, "vm_object_vndeallocate "); | ||||
panic("vm_object_vndeallocate: bad object reference count"); | panic("vm_object_vndeallocate: bad object reference count"); | ||||
} | } | ||||
#endif | #endif | ||||
if (!umtx_shm_vnobj_persistent && object->ref_count == 1) | if (!umtx_shm_vnobj_persistent && object->ref_count == 1) | ||||
umtx_shm_object_terminated(object); | umtx_shm_object_terminated(object); | ||||
/* | |||||
* The test for text of vp vnode does not need a bypass to | |||||
* reach right VV_TEXT there, since it is obtained from | |||||
* object->handle. | |||||
*/ | |||||
if (object->ref_count > 1 || (vp->v_vflag & VV_TEXT) == 0) { | |||||
object->ref_count--; | object->ref_count--; | ||||
VM_OBJECT_WUNLOCK(object); | |||||
/* vrele may need the vnode lock. */ | /* vrele may need the vnode lock. */ | ||||
vrele(vp); | |||||
} else { | |||||
vhold(vp); | |||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); | vrele(vp); | ||||
vdrop(vp); | |||||
VM_OBJECT_WLOCK(object); | |||||
object->ref_count--; | |||||
if (object->type == OBJT_DEAD) { | |||||
VM_OBJECT_WUNLOCK(object); | |||||
VOP_UNLOCK(vp, 0); | |||||
} else { | |||||
if (object->ref_count == 0) | |||||
VOP_UNSET_TEXT(vp); | |||||
VM_OBJECT_WUNLOCK(object); | |||||
vput(vp); | |||||
} | } | ||||
} | |||||
} | |||||
/* | /* | ||||
* vm_object_deallocate: | * vm_object_deallocate: | ||||
* | * | ||||
* Release a reference to the specified object, | * Release a reference to the specified object, | ||||
* gained either through a vm_object_allocate | * gained either through a vm_object_allocate | ||||
* or a vm_object_reference call. When all references | * or a vm_object_reference call. When all references | ||||
* are gone, storage associated with this object | * are gone, storage associated with this object | ||||
▲ Show 20 Lines • Show All 1,211 Lines • ▼ Show 20 Lines | while (TRUE) { | ||||
/* | /* | ||||
* we check the backing object first, because it is most likely | * we check the backing object first, because it is most likely | ||||
* not collapsable. | * not collapsable. | ||||
*/ | */ | ||||
VM_OBJECT_WLOCK(backing_object); | VM_OBJECT_WLOCK(backing_object); | ||||
if (backing_object->handle != NULL || | if (backing_object->handle != NULL || | ||||
(backing_object->type != OBJT_DEFAULT && | (backing_object->type != OBJT_DEFAULT && | ||||
backing_object->type != OBJT_SWAP) || | (backing_object->type != OBJT_SWAP || | ||||
(backing_object->flags & OBJ_NOSPLIT) != 0)) || | |||||
markj: Can you explain why this is needed? Is it intended to catch tmpfs objects? | |||||
Done Inline ActionsYes, this is in fact already existing bug demonstrated by the patch. It destroys content of the tmpfs or posix shared memory backing object by copying all pages to the shadow. kib: Yes, this is in fact already existing bug demonstrated by the patch. It destroys content of… | |||||
Done Inline ActionsI see. Isn't (flags & OBJ_NOSPLIT) == 0 a slightly weird predicate for deciding whether to collapse the backing object? Semantically it seems unrelated. I believe the handle != NULL condition is meant to exclude non-anonymous objects, but tmpfs and shm (including SYSV shm?) do not specify a handle, and I am not aware of any in-tree code that creates a swap object with a handle. markj: I see. Isn't (flags & OBJ_NOSPLIT) == 0 a slightly weird predicate for deciding whether to… | |||||
Done Inline ActionsIt is a weird name but right flag. It means that the content of the object must not be lost. Handles for swap objects cause unneeded lookup, and not too long time ago it was under Giant. All current users of non-anon swap objects have other means to track their objects, and do not need a lookup by handle. kib: It is a weird name but right flag. It means that the content of the object must not be lost. | |||||
(backing_object->flags & OBJ_DEAD) || | (backing_object->flags & OBJ_DEAD) || | ||||
object->handle != NULL || | object->handle != NULL || | ||||
(object->type != OBJT_DEFAULT && | (object->type != OBJT_DEFAULT && | ||||
object->type != OBJT_SWAP) || | object->type != OBJT_SWAP) || | ||||
(object->flags & OBJ_DEAD)) { | (object->flags & OBJ_DEAD)) { | ||||
VM_OBJECT_WUNLOCK(backing_object); | VM_OBJECT_WUNLOCK(backing_object); | ||||
break; | break; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 954 Lines • Show Last 20 Lines |
Can you explain why this is needed? Is it intended to catch tmpfs objects?