diff options
author | Alan Cox <alc@FreeBSD.org> | 2014-09-14 18:07:55 +0000 |
---|---|---|
committer | Alan Cox <alc@FreeBSD.org> | 2014-09-14 18:07:55 +0000 |
commit | 396b3e34b4a9d0c93f98228655007885f74f7ca1 (patch) | |
tree | 2bf12f22e73cb9521683f0cd0d2220af8de44c9a /sys/nfsclient | |
parent | 4a396d7a67d3d5d83f4f0052c7fac28a6734d955 (diff) | |
download | src-test2-396b3e34b4a9d0c93f98228655007885f74f7ca1.tar.gz src-test2-396b3e34b4a9d0c93f98228655007885f74f7ca1.zip |
Avoid an exclusive acquisition of the object lock on the expected execution
path through the NFS clients' getpages functions.
Introduce vm_pager_free_nonreq(). This function can be used to eliminate
code that is duplicated in many getpages functions. Also, in contrast to
the code that currently appears in those getpages functions,
vm_pager_free_nonreq() avoids acquiring an exclusive object lock in one
case.
Reviewed by: kib
MFC after: 6 weeks
Sponsored by: EMC / Isilon Storage Division
Notes
Notes:
svn path=/head/; revision=271596
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 29 |
1 files changed, 9 insertions, 20 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 1f07b4696c9c..1a5b15639d18 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -123,23 +123,20 @@ nfs_getpages(struct vop_getpages_args *ap) npages = btoc(count); /* + * Since the caller has busied the requested page, that page's valid + * field will not be changed by other threads. + */ + vm_page_assert_xbusied(pages[ap->a_reqpage]); + + /* * If the requested page is partially valid, just return it and * allow the pager to zero-out the blanks. Partially valid pages * can only occur at the file EOF. */ - VM_OBJECT_WLOCK(object); if (pages[ap->a_reqpage]->valid != 0) { - for (i = 0; i < npages; ++i) { - if (i != ap->a_reqpage) { - vm_page_lock(pages[i]); - vm_page_free(pages[i]); - vm_page_unlock(pages[i]); - } - } - VM_OBJECT_WUNLOCK(object); - return (0); + vm_pager_free_nonreq(object, pages, ap->a_reqpage, npages); + return (VM_PAGER_OK); } - VM_OBJECT_WUNLOCK(object); /* * We use only the kva address for the buffer, but this is extremely @@ -169,15 +166,7 @@ nfs_getpages(struct vop_getpages_args *ap) if (error && (uio.uio_resid == count)) { nfs_printf("nfs_getpages: error %d\n", error); - VM_OBJECT_WLOCK(object); - for (i = 0; i < npages; ++i) { - if (i != ap->a_reqpage) { - vm_page_lock(pages[i]); - vm_page_free(pages[i]); - vm_page_unlock(pages[i]); - } - } - VM_OBJECT_WUNLOCK(object); + vm_pager_free_nonreq(object, pages, ap->a_reqpage, npages); return (VM_PAGER_ERROR); } |