diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-17 11:59:30 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-20 13:08:26 -0400 |
commit | 3b3be88d67cc17d0f0ab6edaf131516793fc947e (patch) | |
tree | 293bc2bcc7cf7a175786ec33a4e2aff8c5c7ebca /fs/nfs/write.c | |
parent | 5ae67c4fee869c9b3c87b727a9ea511b6326b834 (diff) |
NFS: Use cond_resched_lock() to reduce latencies in the commit scans
Ensure that we conditionally drop the inode->i_lock when it is safe
to do so in the commit loops.
We do so after locking the nfs_page, but before removing it from the
commit list. We can then use list_safe_reset_next to recover the loop
after the lock is retaken.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 628d9a69d0a2..bd93d40099f9 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -561,7 +561,8 @@ nfs_need_commit(struct nfs_inode *nfsi) | |||
561 | 561 | ||
562 | /* i_lock held by caller */ | 562 | /* i_lock held by caller */ |
563 | static int | 563 | static int |
564 | nfs_scan_commit_list(struct list_head *src, struct list_head *dst, int max) | 564 | nfs_scan_commit_list(struct list_head *src, struct list_head *dst, int max, |
565 | spinlock_t *lock) | ||
565 | { | 566 | { |
566 | struct nfs_page *req, *tmp; | 567 | struct nfs_page *req, *tmp; |
567 | int ret = 0; | 568 | int ret = 0; |
@@ -569,6 +570,8 @@ nfs_scan_commit_list(struct list_head *src, struct list_head *dst, int max) | |||
569 | list_for_each_entry_safe(req, tmp, src, wb_list) { | 570 | list_for_each_entry_safe(req, tmp, src, wb_list) { |
570 | if (!nfs_lock_request(req)) | 571 | if (!nfs_lock_request(req)) |
571 | continue; | 572 | continue; |
573 | if (cond_resched_lock(lock)) | ||
574 | list_safe_reset_next(req, tmp, wb_list); | ||
572 | nfs_request_remove_commit_list(req); | 575 | nfs_request_remove_commit_list(req); |
573 | nfs_list_add_request(req, dst); | 576 | nfs_list_add_request(req, dst); |
574 | ret++; | 577 | ret++; |
@@ -596,8 +599,10 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst) | |||
596 | if (nfsi->ncommit > 0) { | 599 | if (nfsi->ncommit > 0) { |
597 | const int max = INT_MAX; | 600 | const int max = INT_MAX; |
598 | 601 | ||
599 | ret = nfs_scan_commit_list(&nfsi->commit_list, dst, max); | 602 | ret = nfs_scan_commit_list(&nfsi->commit_list, dst, max, |
600 | ret += pnfs_scan_commit_lists(inode, max - ret); | 603 | &inode->i_lock); |
604 | ret += pnfs_scan_commit_lists(inode, max - ret, | ||
605 | &inode->i_lock); | ||
601 | } | 606 | } |
602 | spin_unlock(&inode->i_lock); | 607 | spin_unlock(&inode->i_lock); |
603 | return ret; | 608 | return ret; |