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;
 };
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to