aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2020-07-27 14:25:10 +0000
committerMark Johnston <markj@FreeBSD.org>2020-07-27 14:25:10 +0000
commit782ebde52ef5e51fe8fb5161e65c18c351537a20 (patch)
treeb358659456c4136d4fe1a32c43ec8df73643f8ff
parent58f5de0d8afaf8423b87a613a4a0772e56f8f72a (diff)
downloadsrc-782ebde52ef5e51fe8fb5161e65c18c351537a20.tar.gz
src-782ebde52ef5e51fe8fb5161e65c18c351537a20.zip
vm_page_free_invalid(): Relax the xbusy assertion.
vm_page_assert_xbusied() asserts that the busying thread is the current thread. For some uses of vm_page_free_invalid() (e.g., error handling in vnode_pager_generic_getpages_done()), this condition might not hold. Reported by: Jenkins via trasz Reviewed by: chs, kib Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D25828
Notes
Notes: svn path=/head/; revision=363607
-rw-r--r--sys/vm/vm_page.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index a7d6f3dd9d64..8c2df3e78e17 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -1371,11 +1371,16 @@ vm_page_free_invalid(vm_page_t m)
KASSERT(vm_page_none_valid(m), ("page %p is valid", m));
KASSERT(!pmap_page_is_mapped(m), ("page %p is mapped", m));
- vm_page_assert_xbusied(m);
KASSERT(m->object != NULL, ("page %p has no object", m));
VM_OBJECT_ASSERT_WLOCKED(m->object);
/*
+ * We may be attempting to free the page as part of the handling for an
+ * I/O error, in which case the page was xbusied by a different thread.
+ */
+ vm_page_xbusy_claim(m);
+
+ /*
* If someone has wired this page while the object lock
* was not held, then the thread that unwires is responsible
* for freeing the page. Otherwise just free the page now.