diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2025-08-05 15:46:56 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2025-09-14 20:00:36 +0000 |
| commit | a38483fa2b3a26414d3409b12dd35ac406c44cea (patch) | |
| tree | 92495f15dd04b22d3890077e276a1ccb35333287 | |
| parent | 149674bbac5842ac883414a6c1e75d829c70d42b (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.c | 8 |
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 |
