summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_object.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_object.c')
-rw-r--r--sys/vm/vm_object.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index e9d1280..5ea59b3 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -1673,11 +1673,11 @@ vm_object_qcollapse(vm_object_t object)
void
vm_object_collapse(vm_object_t object)
{
+ vm_object_t backing_object, new_backing_object;
+
VM_OBJECT_ASSERT_WLOCKED(object);
-
- while (TRUE) {
- vm_object_t backing_object;
+ while (TRUE) {
/*
* Verify that the conditions are right for collapse:
*
@@ -1703,14 +1703,13 @@ vm_object_collapse(vm_object_t object)
break;
}
- if (
- object->paging_in_progress != 0 ||
- backing_object->paging_in_progress != 0
- ) {
+ if (object->paging_in_progress != 0 ||
+ backing_object->paging_in_progress != 0) {
vm_object_qcollapse(object);
VM_OBJECT_WUNLOCK(backing_object);
break;
}
+
/*
* We know that we can either collapse the backing object (if
* the parent is the only reference to it) or (perhaps) have
@@ -1722,6 +1721,9 @@ vm_object_collapse(vm_object_t object)
* case.
*/
if (backing_object->ref_count == 1) {
+ vm_object_pip_add(object, 1);
+ vm_object_pip_add(backing_object, 1);
+
/*
* If there is exactly one reference to the backing
* object, we can collapse it into the parent.
@@ -1793,15 +1795,15 @@ vm_object_collapse(vm_object_t object)
KASSERT(backing_object->ref_count == 1, (
"backing_object %p was somehow re-referenced during collapse!",
backing_object));
+ vm_object_pip_wakeup(backing_object);
backing_object->type = OBJT_DEAD;
backing_object->ref_count = 0;
VM_OBJECT_WUNLOCK(backing_object);
vm_object_destroy(backing_object);
+ vm_object_pip_wakeup(object);
object_collapses++;
} else {
- vm_object_t new_backing_object;
-
/*
* If we do not entirely shadow the backing object,
* there is nothing we can do so we give up.
@@ -2130,6 +2132,7 @@ vm_object_coalesce(vm_object_t prev_object, vm_ooffset_t prev_offset,
*/
if (!reserved && !swap_reserve_by_cred(ptoa(next_size),
prev_object->cred)) {
+ VM_OBJECT_WUNLOCK(prev_object);
return (FALSE);
}
prev_object->charge += ptoa(next_size);
OpenPOWER on IntegriCloud