diff options
author | alc <alc@FreeBSD.org> | 2008-02-24 18:03:56 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2008-02-24 18:03:56 +0000 |
commit | c69581f28f1b37e64e8db470518170a857d59199 (patch) | |
tree | bf88a6f3148e00e3e78d7f29806699b3ff5a8843 /sys | |
parent | 9ba4f3d00623bf0256e4a363444823519f9fb8b1 (diff) | |
download | FreeBSD-src-c69581f28f1b37e64e8db470518170a857d59199.zip FreeBSD-src-c69581f28f1b37e64e8db470518170a857d59199.tar.gz |
Correct a long-standing error in vm_object_deallocate(). Specifically,
only anonymous default (OBJT_DEFAULT) and swap (OBJT_SWAP) objects should
ever have OBJ_ONEMAPPING set. However, vm_object_deallocate() was
setting it on device (OBJT_DEVICE) objects. As a result,
vm_object_page_remove() could be called on a device object and if that
occurred pmap_remove_all() would be called on the device object's pages.
However, a device object's pages are fictitious, and fictitious pages do
not have an initialized pv list (struct md_page).
To date, fictitious pages have been allocated from zeroed memory,
effectively hiding this problem. Now, however, the conversion of rotting
diagnostics to invariants in the amd64 and i386 pmaps has revealed the
problem. Specifically, assertion failures have occurred during the
initialization phase of the X server on some hardware.
MFC after: 1 week
Discussed with: Kostik Belousov
Reported by: Michiel Boland
Diffstat (limited to 'sys')
-rw-r--r-- | sys/vm/vm_object.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 9df34ea..66ec1e9 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -500,7 +500,10 @@ vm_object_deallocate(vm_object_t object) VM_OBJECT_UNLOCK(object); return; } else if (object->ref_count == 1) { - if (object->shadow_count == 0) { + if (object->shadow_count == 0 && + object->handle == NULL && + (object->type == OBJT_DEFAULT || + object->type == OBJT_SWAP)) { vm_object_set_flag(object, OBJ_ONEMAPPING); } else if ((object->shadow_count == 1) && (object->handle == NULL) && |