svn commit: r357024 - head/sys/vm
Jeff Roberson
jeff at FreeBSD.org
Thu Jan 23 05:14:41 UTC 2020
Author: jeff
Date: Thu Jan 23 05:14:41 2020
New Revision: 357024
URL: https://svnweb.freebsd.org/changeset/base/357024
Log:
(fault 5/9) Move the backing_object traversal into a dedicated function.
Reviewed by: dougm, kib, markj
Differential Revision: https://reviews.freebsd.org/D23310
Modified:
head/sys/vm/vm_fault.c
Modified: head/sys/vm/vm_fault.c
==============================================================================
--- head/sys/vm/vm_fault.c Thu Jan 23 05:11:01 2020 (r357023)
+++ head/sys/vm/vm_fault.c Thu Jan 23 05:14:41 2020 (r357024)
@@ -932,6 +932,75 @@ vm_fault_cow(struct faultstate *fs)
curthread->td_cow++;
}
+static bool
+vm_fault_next(struct faultstate *fs)
+{
+ vm_object_t next_object;
+
+ /*
+ * The requested page does not exist at this object/
+ * offset. Remove the invalid page from the object,
+ * waking up anyone waiting for it, and continue on to
+ * the next object. However, if this is the top-level
+ * object, we must leave the busy page in place to
+ * prevent another process from rushing past us, and
+ * inserting the page in that object at the same time
+ * that we are.
+ */
+ if (fs->object == fs->first_object) {
+ fs->first_m = fs->m;
+ fs->m = NULL;
+ } else
+ fault_page_free(&fs->m);
+
+ /*
+ * Move on to the next object. Lock the next object before
+ * unlocking the current one.
+ */
+ VM_OBJECT_ASSERT_WLOCKED(fs->object);
+ next_object = fs->object->backing_object;
+ if (next_object == NULL) {
+ /*
+ * If there's no object left, fill the page in the top
+ * object with zeros.
+ */
+ VM_OBJECT_WUNLOCK(fs->object);
+ if (fs->object != fs->first_object) {
+ vm_object_pip_wakeup(fs->object);
+ fs->object = fs->first_object;
+ fs->pindex = fs->first_pindex;
+ }
+ MPASS(fs->first_m != NULL);
+ MPASS(fs->m == NULL);
+ fs->m = fs->first_m;
+ fs->first_m = NULL;
+
+ /*
+ * Zero the page if necessary and mark it valid.
+ */
+ if ((fs->m->flags & PG_ZERO) == 0) {
+ pmap_zero_page(fs->m);
+ } else {
+ VM_CNT_INC(v_ozfod);
+ }
+ VM_CNT_INC(v_zfod);
+ vm_page_valid(fs->m);
+
+ return (false);
+ }
+ MPASS(fs->first_m != NULL);
+ KASSERT(fs->object != next_object, ("object loop %p", next_object));
+ VM_OBJECT_WLOCK(next_object);
+ vm_object_pip_add(next_object, 1);
+ if (fs->object != fs->first_object)
+ vm_object_pip_wakeup(fs->object);
+ fs->pindex += OFF_TO_IDX(fs->object->backing_object_offset);
+ VM_OBJECT_WUNLOCK(fs->object);
+ fs->object = next_object;
+
+ return (true);
+}
+
/*
* Wait/Retry if the page is busy. We have to do this if the page is
* either exclusive or shared busy because the vm_pager may be using
@@ -974,7 +1043,6 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fa
{
struct faultstate fs;
struct domainset *dset;
- vm_object_t next_object;
vm_offset_t e_end, e_start;
int ahead, alloc_req, behind, cluster_offset, faultcount;
int nera, oom, result, rv;
@@ -1187,8 +1255,13 @@ readrest:
* object without dropping the lock to preserve atomicity of
* shadow faults.
*/
- if (fs.object->type == OBJT_DEFAULT)
- goto next;
+ if (fs.object->type == OBJT_DEFAULT) {
+ if (vm_fault_next(&fs))
+ continue;
+ /* Don't try to prefault neighboring pages. */
+ faultcount = 1;
+ break;
+ }
/*
* At this point, we have either allocated a new page or found
@@ -1304,70 +1377,14 @@ readrest:
}
-next:
/*
- * The requested page does not exist at this object/
- * offset. Remove the invalid page from the object,
- * waking up anyone waiting for it, and continue on to
- * the next object. However, if this is the top-level
- * object, we must leave the busy page in place to
- * prevent another process from rushing past us, and
- * inserting the page in that object at the same time
- * that we are.
+ * The page was not found in the current object. Try to traverse
+ * into a backing object or zero fill if none is found.
*/
- if (fs.object == fs.first_object) {
- fs.first_m = fs.m;
- fs.m = NULL;
- } else
- fault_page_free(&fs.m);
-
- /*
- * Move on to the next object. Lock the next object before
- * unlocking the current one.
- */
- VM_OBJECT_ASSERT_WLOCKED(fs.object);
- next_object = fs.object->backing_object;
- if (next_object == NULL) {
- /*
- * If there's no object left, fill the page in the top
- * object with zeros.
- */
- VM_OBJECT_WUNLOCK(fs.object);
- if (fs.object != fs.first_object) {
- vm_object_pip_wakeup(fs.object);
- fs.object = fs.first_object;
- fs.pindex = fs.first_pindex;
- }
- MPASS(fs.first_m != NULL);
- MPASS(fs.m == NULL);
- fs.m = fs.first_m;
- fs.first_m = NULL;
-
- /*
- * Zero the page if necessary and mark it valid.
- */
- if ((fs.m->flags & PG_ZERO) == 0) {
- pmap_zero_page(fs.m);
- } else {
- VM_CNT_INC(v_ozfod);
- }
- VM_CNT_INC(v_zfod);
- vm_page_valid(fs.m);
+ if (!vm_fault_next(&fs)) {
/* Don't try to prefault neighboring pages. */
faultcount = 1;
break; /* break to PAGE HAS BEEN FOUND. */
- } else {
- MPASS(fs.first_m != NULL);
- KASSERT(fs.object != next_object,
- ("object loop %p", next_object));
- VM_OBJECT_WLOCK(next_object);
- vm_object_pip_add(next_object, 1);
- if (fs.object != fs.first_object)
- vm_object_pip_wakeup(fs.object);
- fs.pindex +=
- OFF_TO_IDX(fs.object->backing_object_offset);
- VM_OBJECT_WUNLOCK(fs.object);
- fs.object = next_object;
}
}
More information about the svn-src-head
mailing list