Author: alc
Date: Sun May  2 19:10:27 2010
New Revision: 207534
URL: http://svn.freebsd.org/changeset/base/207534

Log:
  Properly synchronize access to the page's hold_count in vfs_vmio_release().
  
  Reviewed by:  kib

Modified:
  head/sys/kern/vfs_bio.c

Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c     Sun May  2 19:07:19 2010        (r207533)
+++ head/sys/kern/vfs_bio.c     Sun May  2 19:10:27 2010        (r207534)
@@ -1563,7 +1563,6 @@ vfs_vmio_release(struct buf *bp)
        vm_page_t m;
 
        VM_OBJECT_LOCK(bp->b_bufobj->bo_object);
-       vm_page_lock_queues();
        for (i = 0; i < bp->b_npages; i++) {
                m = bp->b_pages[i];
                bp->b_pages[i] = NULL;
@@ -1571,16 +1570,16 @@ vfs_vmio_release(struct buf *bp)
                 * In order to keep page LRU ordering consistent, put
                 * everything on the inactive queue.
                 */
+               vm_page_lock(m);
+               vm_page_lock_queues();
                vm_page_unwire(m, 0);
                /*
                 * We don't mess with busy pages, it is
                 * the responsibility of the process that
                 * busied the pages to deal with them.
                 */
-               if ((m->oflags & VPO_BUSY) || (m->busy != 0))
-                       continue;
-                       
-               if (m->wire_count == 0) {
+               if ((m->oflags & VPO_BUSY) == 0 && m->busy == 0 &&
+                   m->wire_count == 0) {
                        /*
                         * Might as well free the page if we can and it has
                         * no valid data.  We also free the page if the
@@ -1595,8 +1594,9 @@ vfs_vmio_release(struct buf *bp)
                                vm_page_try_to_cache(m);
                        }
                }
+               vm_page_unlock_queues();
+               vm_page_unlock(m);
        }
-       vm_page_unlock_queues();
        VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object);
        pmap_qremove(trunc_page((vm_offset_t) bp->b_data), bp->b_npages);
        
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to