summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authormlaier <mlaier@FreeBSD.org>2011-05-09 20:27:49 +0000
committermlaier <mlaier@FreeBSD.org>2011-05-09 20:27:49 +0000
commit39f7e10a268694e139c11157f966ca179b834212 (patch)
tree262cf61557621fe4c03f96dd93d63e53a18ee0cb /sys/vm
parentdcff3b06939d65d6fcd273cb05955efcbd6b0d1d (diff)
downloadFreeBSD-src-39f7e10a268694e139c11157f966ca179b834212.zip
FreeBSD-src-39f7e10a268694e139c11157f966ca179b834212.tar.gz
Another long standing vm bug found at Isilon:
Fix a race between vm_object_collapse and vm_fault. Reviewed by: alc@ MFC after: 3 days
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_object.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 5df2f31..dbcac85 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -1468,6 +1468,24 @@ vm_object_backing_scan(vm_object_t object, int op)
pp = vm_page_lookup(object, new_pindex);
if (
+ (op & OBSC_COLLAPSE_NOWAIT) != 0 &&
+ (pp != NULL && pp->valid == 0)
+ ) {
+ /*
+ * The page in the parent is not (yet) valid.
+ * We don't know anything about the state of
+ * the original page. It might be mapped,
+ * so we must avoid the next if here.
+ *
+ * This is due to a race in vm_fault() where
+ * we must unbusy the original (backing_obj)
+ * page before we can (re)lock the parent.
+ * Hence we can get here.
+ */
+ p = next;
+ continue;
+ }
+ if (
pp != NULL ||
vm_pager_has_page(object, new_pindex, NULL, NULL)
) {
OpenPOWER on IntegriCloud