diff options
author | mlaier <mlaier@FreeBSD.org> | 2011-05-09 20:27:49 +0000 |
---|---|---|
committer | mlaier <mlaier@FreeBSD.org> | 2011-05-09 20:27:49 +0000 |
commit | 39f7e10a268694e139c11157f966ca179b834212 (patch) | |
tree | 262cf61557621fe4c03f96dd93d63e53a18ee0cb /sys/vm | |
parent | dcff3b06939d65d6fcd273cb05955efcbd6b0d1d (diff) | |
download | FreeBSD-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.c | 18 |
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) ) { |