aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2025-08-05 15:46:56 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2025-09-14 20:00:36 +0000
commita38483fa2b3a26414d3409b12dd35ac406c44cea (patch)
tree92495f15dd04b22d3890077e276a1ccb35333287
parent149674bbac5842ac883414a6c1e75d829c70d42b (diff)
vm_fault: assert that first_m is xbusy
There are several invariants, most important of which is prevention of parallel faults handling, that depend on first_m being xbusy for the duration of the page fault processing. Suggested by: markj Reviewed by: alc, markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D51474
-rw-r--r--sys/vm/vm_fault.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 427c18c63eb7..3dddc7a307d4 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -1784,6 +1784,11 @@ found:
/*
* A valid page has been found and busied. The object lock
* must no longer be held if the page was busied.
+ *
+ * Regardless of the busy state of fs.m, fs.first_m is always
+ * exclusively busied after the first iteration of the loop
+ * calling vm_fault_object(). This is an ordering point for
+ * the parallel faults occuring in on the same page.
*/
vm_page_assert_busied(fs.m);
VM_OBJECT_ASSERT_UNLOCKED(fs.object);
@@ -1886,6 +1891,9 @@ found:
(*fs.m_hold) = fs.m;
vm_page_wire(fs.m);
}
+
+ KASSERT(fs.first_object == fs.object || vm_page_xbusied(fs.first_m),
+ ("first_m must be xbusy"));
if (vm_page_xbusied(fs.m))
vm_page_xunbusy(fs.m);
else