svn commit: r356936 - head/sys/vm

Jeff Roberson jeff at FreeBSD.org
Tue Jan 21 00:12:58 UTC 2020


Author: jeff
Date: Tue Jan 21 00:12:57 2020
New Revision: 356936
URL: https://svnweb.freebsd.org/changeset/base/356936

Log:
  Move readahead and dropbehind fault functionality into a helper routine for
  clarity.
  
  Reviewed by:	dougm, kib, markj
  Differential Revision:	https://reviews.freebsd.org/D23282

Modified:
  head/sys/vm/vm_fault.c

Modified: head/sys/vm/vm_fault.c
==============================================================================
--- head/sys/vm/vm_fault.c	Mon Jan 20 23:44:10 2020	(r356935)
+++ head/sys/vm/vm_fault.c	Tue Jan 21 00:12:57 2020	(r356936)
@@ -120,6 +120,7 @@ __FBSDID("$FreeBSD$");
 #define	VM_FAULT_DONTNEED_MIN	1048576
 
 struct faultstate {
+	vm_offset_t vaddr;
 	vm_page_t m;
 	vm_page_t m_cow;
 	vm_object_t object;
@@ -680,6 +681,59 @@ vm_fault_lock_vnode(struct faultstate *fs, bool objloc
 }
 
 /*
+ * Calculate the desired readahead.  Handle drop-behind.
+ *
+ * Returns the number of readahead blocks to pass to the pager.
+ */
+static int
+vm_fault_readahead(struct faultstate *fs)
+{
+	int era, nera;
+	u_char behavior;
+
+	KASSERT(fs->lookup_still_valid, ("map unlocked"));
+	era = fs->entry->read_ahead;
+	behavior = vm_map_entry_behavior(fs->entry);
+	if (behavior == MAP_ENTRY_BEHAV_RANDOM) {
+		nera = 0;
+	} else if (behavior == MAP_ENTRY_BEHAV_SEQUENTIAL) {
+		nera = VM_FAULT_READ_AHEAD_MAX;
+		if (fs->vaddr == fs->entry->next_read)
+			vm_fault_dontneed(fs, fs->vaddr, nera);
+	} else if (fs->vaddr == fs->entry->next_read) {
+		/*
+		 * This is a sequential fault.  Arithmetically
+		 * increase the requested number of pages in
+		 * the read-ahead window.  The requested
+		 * number of pages is "# of sequential faults
+		 * x (read ahead min + 1) + read ahead min"
+		 */
+		nera = VM_FAULT_READ_AHEAD_MIN;
+		if (era > 0) {
+			nera += era + 1;
+			if (nera > VM_FAULT_READ_AHEAD_MAX)
+				nera = VM_FAULT_READ_AHEAD_MAX;
+		}
+		if (era == VM_FAULT_READ_AHEAD_MAX)
+			vm_fault_dontneed(fs, fs->vaddr, nera);
+	} else {
+		/*
+		 * This is a non-sequential fault.
+		 */
+		nera = 0;
+	}
+	if (era != nera) {
+		/*
+		 * A read lock on the map suffices to update
+		 * the read ahead count safely.
+		 */
+		fs->entry->read_ahead = nera;
+	}
+
+	return (nera);
+}
+
+/*
  * 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
  * read busy for pageouts (and even pageins if it is the vnode pager),
@@ -725,7 +779,7 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fa
 	vm_offset_t e_end, e_start;
 	vm_pindex_t retry_pindex;
 	vm_prot_t prot, retry_prot;
-	int ahead, alloc_req, behind, cluster_offset, era, faultcount;
+	int ahead, alloc_req, behind, cluster_offset, faultcount;
 	int nera, oom, result, rv;
 	u_char behavior;
 	boolean_t wired;	/* Passed by reference. */
@@ -737,6 +791,7 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fa
 		return (KERN_PROTECTION_FAILURE);
 
 	fs.vp = NULL;
+	fs.vaddr = vaddr;
 	faultcount = 0;
 	nera = -1;
 	hardfault = false;
@@ -989,45 +1044,7 @@ readrest:
 		 * apply to subsequent objects in the shadow chain.
 		 */
 		if (nera == -1 && !P_KILLED(curproc)) {
-			KASSERT(fs.lookup_still_valid, ("map unlocked"));
-			era = fs.entry->read_ahead;
-			behavior = vm_map_entry_behavior(fs.entry);
-			if (behavior == MAP_ENTRY_BEHAV_RANDOM) {
-				nera = 0;
-			} else if (behavior == MAP_ENTRY_BEHAV_SEQUENTIAL) {
-				nera = VM_FAULT_READ_AHEAD_MAX;
-				if (vaddr == fs.entry->next_read)
-					vm_fault_dontneed(&fs, vaddr, nera);
-			} else if (vaddr == fs.entry->next_read) {
-				/*
-				 * This is a sequential fault.  Arithmetically
-				 * increase the requested number of pages in
-				 * the read-ahead window.  The requested
-				 * number of pages is "# of sequential faults
-				 * x (read ahead min + 1) + read ahead min"
-				 */
-				nera = VM_FAULT_READ_AHEAD_MIN;
-				if (era > 0) {
-					nera += era + 1;
-					if (nera > VM_FAULT_READ_AHEAD_MAX)
-						nera = VM_FAULT_READ_AHEAD_MAX;
-				}
-				if (era == VM_FAULT_READ_AHEAD_MAX)
-					vm_fault_dontneed(&fs, vaddr, nera);
-			} else {
-				/*
-				 * This is a non-sequential fault.
-				 */
-				nera = 0;
-			}
-			if (era != nera) {
-				/*
-				 * A read lock on the map suffices to update
-				 * the read ahead count safely.
-				 */
-				fs.entry->read_ahead = nera;
-			}
-
+			nera = vm_fault_readahead(&fs);
 			/*
 			 * Prepare for unlocking the map.  Save the map
 			 * entry's start and end addresses, which are used to
@@ -1038,6 +1055,7 @@ readrest:
 			 */
 			e_start = fs.entry->start;
 			e_end = fs.entry->end;
+			behavior = vm_map_entry_behavior(fs.entry);
 		}
 
 		/*


More information about the svn-src-all mailing list