From aa9bc3b1710cdd08d12d524f5f6ca522e306c24e Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 26 May 2016 16:59:29 +0000 Subject: [PATCH] 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 --- sys/vm/vm_object.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 0ebecc451a7..88bc593ab50 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 { /*