svn commit: r302399 - head/sys/vm

Alan Cox alc at FreeBSD.org
Thu Jul 7 20:58:18 UTC 2016


Author: alc
Date: Thu Jul  7 20:58:16 2016
New Revision: 302399
URL: https://svnweb.freebsd.org/changeset/base/302399

Log:
  Change the type of the map entry's next_read field from a vm_pindex_t to a
  vm_offset_t.  (This field is used to detect sequential access to the virtual
  address range represented by the map entry.)  There are three reasons to
  make this change.  First, a vm_offset_t is smaller on 32-bit architectures.
  Consequently, a struct vm_map_entry is now smaller on 32-bit architectures.
  Second, a vm_offset_t can be written atomically, whereas it may not be
  possible to write a vm_pindex_t atomically on a 32-bit architecture.  Third,
  using a vm_pindex_t makes the next_read field dependent on which object in
  the shadow chain is being read from.
  
  Replace an "XXX" comment.
  
  Reviewed by:	kib
  Approved by:	re (gjb)
  Sponsored by:	EMC / Isilon Storage Division

Modified:
  head/sys/vm/vm_fault.c
  head/sys/vm/vm_map.c
  head/sys/vm/vm_map.h

Modified: head/sys/vm/vm_fault.c
==============================================================================
--- head/sys/vm/vm_fault.c	Thu Jul  7 20:50:59 2016	(r302398)
+++ head/sys/vm/vm_fault.c	Thu Jul  7 20:58:16 2016	(r302399)
@@ -570,9 +570,9 @@ readrest:
 				behind = 0;
 				nera = VM_FAULT_READ_AHEAD_MAX;
 				ahead = nera;
-				if (fs.pindex == fs.entry->next_read)
+				if (vaddr == fs.entry->next_read)
 					vm_fault_dontneed(&fs, vaddr, ahead);
-			} else if (fs.pindex == fs.entry->next_read) {
+			} else if (vaddr == fs.entry->next_read) {
 				/*
 				 * This is a sequential fault.  Arithmetically
 				 * increase the requested number of pages in
@@ -927,15 +927,15 @@ vnode_locked:
 			prot &= retry_prot;
 		}
 	}
+
 	/*
-	 * If the page was filled by a pager, update the map entry's
-	 * last read offset.
-	 *
-	 * XXX The following assignment modifies the map
-	 * without holding a write lock on it.
+	 * If the page was filled by a pager, save the virtual address that
+	 * should be faulted on next under a sequential access pattern to the
+	 * map entry.  A read lock on the map suffices to update this address
+	 * safely.
 	 */
 	if (hardfault)
-		fs.entry->next_read = fs.pindex + ahead + 1;
+		fs.entry->next_read = vaddr + ptoa(ahead) + PAGE_SIZE;
 
 	vm_fault_dirty(fs.entry, fs.m, prot, fault_type, fault_flags, TRUE);
 	vm_page_assert_xbusied(fs.m);

Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c	Thu Jul  7 20:50:59 2016	(r302398)
+++ head/sys/vm/vm_map.c	Thu Jul  7 20:58:16 2016	(r302399)
@@ -1330,7 +1330,7 @@ charged:
 	new_entry->wired_count = 0;
 	new_entry->wiring_thread = NULL;
 	new_entry->read_ahead = VM_FAULT_READ_AHEAD_INIT;
-	new_entry->next_read = OFF_TO_IDX(offset);
+	new_entry->next_read = start;
 
 	KASSERT(cred == NULL || !ENTRY_CHARGED(new_entry),
 	    ("OVERCOMMIT: vm_map_insert leaks vm_map %p", new_entry));

Modified: head/sys/vm/vm_map.h
==============================================================================
--- head/sys/vm/vm_map.h	Thu Jul  7 20:50:59 2016	(r302398)
+++ head/sys/vm/vm_map.h	Thu Jul  7 20:58:16 2016	(r302399)
@@ -104,6 +104,7 @@ struct vm_map_entry {
 	vm_offset_t start;		/* start address */
 	vm_offset_t end;		/* end address */
 	vm_offset_t avail_ssize;	/* amt can grow if this is a stack */
+	vm_offset_t next_read;		/* vaddr of the next sequential read */
 	vm_size_t adj_free;		/* amount of adjacent free space */
 	vm_size_t max_free;		/* max free space in subtree */
 	union vm_map_object object;	/* object I point to */
@@ -114,7 +115,6 @@ struct vm_map_entry {
 	vm_inherit_t inheritance;	/* inheritance */
 	uint8_t read_ahead;		/* pages in the read-ahead window */
 	int wired_count;		/* can be paged if = 0 */
-	vm_pindex_t next_read;		/* index of the next sequential read */
 	struct ucred *cred;		/* tmp storage for creator ref */
 	struct thread *wiring_thread;
 };


More information about the svn-src-head mailing list