summaryrefslogtreecommitdiff
path: root/sys/nfsclient
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2014-09-14 18:07:55 +0000
committerAlan Cox <alc@FreeBSD.org>2014-09-14 18:07:55 +0000
commit396b3e34b4a9d0c93f98228655007885f74f7ca1 (patch)
tree2bf12f22e73cb9521683f0cd0d2220af8de44c9a /sys/nfsclient
parent4a396d7a67d3d5d83f4f0052c7fac28a6734d955 (diff)
downloadsrc-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.c29
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);
}