summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-05-26 16:59:29 +0000
committerkib <kib@FreeBSD.org>2016-05-26 16:59:29 +0000
commitf11f5ba812de1ae12064f700f60e969f68dbb984 (patch)
tree727db65fdef51ecc1f0b0c264ecb933fe3774e4d
parent3c784f29dd2bf78a64b9cbd669c8e9ccc08ea9aa (diff)
downloadFreeBSD-src-f11f5ba812de1ae12064f700f60e969f68dbb984.zip
FreeBSD-src-f11f5ba812de1ae12064f700f60e969f68dbb984.tar.gz
Prevent parallel object collapses. Both vm_object_collapse_scan() and
swap_pager_copy() might unlock the object, which allows the parallel collapse to execute. Besides destroying the object, it also might move the reference from parent to the backing object, firing the assertion ref_count == 1. Collapses are prevented by bumping paging_in_progress counters on both the object and its backing object. Reported by: cem Tested by: pho (previous version) Reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 1 week X-Differential revision: https://reviews.freebsd.org/D6085
-rw-r--r--sys/vm/vm_object.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 0ebecc4..88bc593 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -1717,6 +1717,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.
@@ -1788,11 +1791,13 @@ 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 {
/*
OpenPOWER on IntegriCloud