Author: alc
Date: Sat Sep 13 18:26:13 2014
New Revision: 271540
URL: http://svnweb.freebsd.org/changeset/base/271540

Log:
  We don't need an exclusive object lock on the expected execution path
  through {ext2,ffs}_getpages().
  
  Reviewed by:  kib, pfg
  MFC after:    6 weeks
  Sponsored by: EMC / Isilon Storage Division

Modified:
  head/sys/fs/ext2fs/ext2_vnops.c
  head/sys/ufs/ffs/ffs_vnops.c

Modified: head/sys/fs/ext2fs/ext2_vnops.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_vnops.c     Sat Sep 13 18:24:54 2014        
(r271539)
+++ head/sys/fs/ext2fs/ext2_vnops.c     Sat Sep 13 18:26:13 2014        
(r271540)
@@ -2074,19 +2074,25 @@ ext2_getpages(struct vop_getpages_args *
        vm_page_t mreq;
        int pcount;
 
-       pcount = round_page(ap->a_count) / PAGE_SIZE;
        mreq = ap->a_m[ap->a_reqpage];
 
        /*
+        * Since the caller has busied the requested page, that page's valid
+        * field will not be changed by other threads.
+        */
+       vm_page_assert_xbusied(mreq);
+
+       /*
         * if ANY DEV_BSIZE blocks are valid on a large filesystem block,
         * then the entire page is valid.  Since the page may be mapped,
         * user programs might reference data beyond the actual end of file
         * occuring within the page.  We have to zero that data.
         */
-       VM_OBJECT_WLOCK(mreq->object);
        if (mreq->valid) {
+               VM_OBJECT_WLOCK(mreq->object);
                if (mreq->valid != VM_PAGE_BITS_ALL)
                        vm_page_zero_invalid(mreq, TRUE);
+               pcount = round_page(ap->a_count) / PAGE_SIZE;
                for (i = 0; i < pcount; i++) {
                        if (i != ap->a_reqpage) {
                                vm_page_lock(ap->a_m[i]);
@@ -2097,7 +2103,6 @@ ext2_getpages(struct vop_getpages_args *
                VM_OBJECT_WUNLOCK(mreq->object);
                return VM_PAGER_OK;
        }
-       VM_OBJECT_WUNLOCK(mreq->object);
 
        return vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
                                            ap->a_count,

Modified: head/sys/ufs/ffs/ffs_vnops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vnops.c        Sat Sep 13 18:24:54 2014        
(r271539)
+++ head/sys/ufs/ffs/ffs_vnops.c        Sat Sep 13 18:26:13 2014        
(r271540)
@@ -857,19 +857,25 @@ ffs_getpages(ap)
        vm_page_t mreq;
        int pcount;
 
-       pcount = round_page(ap->a_count) / PAGE_SIZE;
        mreq = ap->a_m[ap->a_reqpage];
 
        /*
+        * Since the caller has busied the requested page, that page's valid
+        * field will not be changed by other threads.
+        */
+       vm_page_assert_xbusied(mreq);
+
+       /*
         * if ANY DEV_BSIZE blocks are valid on a large filesystem block,
         * then the entire page is valid.  Since the page may be mapped,
         * user programs might reference data beyond the actual end of file
         * occuring within the page.  We have to zero that data.
         */
-       VM_OBJECT_WLOCK(mreq->object);
        if (mreq->valid) {
+               VM_OBJECT_WLOCK(mreq->object);
                if (mreq->valid != VM_PAGE_BITS_ALL)
                        vm_page_zero_invalid(mreq, TRUE);
+               pcount = round_page(ap->a_count) / PAGE_SIZE;
                for (i = 0; i < pcount; i++) {
                        if (i != ap->a_reqpage) {
                                vm_page_lock(ap->a_m[i]);
@@ -880,7 +886,6 @@ ffs_getpages(ap)
                VM_OBJECT_WUNLOCK(mreq->object);
                return VM_PAGER_OK;
        }
-       VM_OBJECT_WUNLOCK(mreq->object);
 
        return vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
                                            ap->a_count,
_______________________________________________
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