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/nfs4filelayout.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/nfs4filelayout.c')
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index e0bdbf4fe454..634c0bcb4fd6 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -936,7 +936,8 @@ static struct pnfs_layout_segment *find_only_write_lseg(struct inode *inode) | |||
936 | } | 936 | } |
937 | 937 | ||
938 | static int | 938 | static int |
939 | filelayout_scan_ds_commit_list(struct nfs4_fl_commit_bucket *bucket, int max) | 939 | filelayout_scan_ds_commit_list(struct nfs4_fl_commit_bucket *bucket, int max, |
940 | spinlock_t *lock) | ||
940 | { | 941 | { |
941 | struct list_head *src = &bucket->written; | 942 | struct list_head *src = &bucket->written; |
942 | struct list_head *dst = &bucket->committing; | 943 | struct list_head *dst = &bucket->committing; |
@@ -946,6 +947,8 @@ filelayout_scan_ds_commit_list(struct nfs4_fl_commit_bucket *bucket, int max) | |||
946 | list_for_each_entry_safe(req, tmp, src, wb_list) { | 947 | list_for_each_entry_safe(req, tmp, src, wb_list) { |
947 | if (!nfs_lock_request(req)) | 948 | if (!nfs_lock_request(req)) |
948 | continue; | 949 | continue; |
950 | if (cond_resched_lock(lock)) | ||
951 | list_safe_reset_next(req, tmp, wb_list); | ||
949 | nfs_request_remove_commit_list(req); | 952 | nfs_request_remove_commit_list(req); |
950 | clear_bit(PG_COMMIT_TO_DS, &req->wb_flags); | 953 | clear_bit(PG_COMMIT_TO_DS, &req->wb_flags); |
951 | nfs_list_add_request(req, dst); | 954 | nfs_list_add_request(req, dst); |
@@ -959,7 +962,8 @@ filelayout_scan_ds_commit_list(struct nfs4_fl_commit_bucket *bucket, int max) | |||
959 | /* Move reqs from written to committing lists, returning count of number moved. | 962 | /* Move reqs from written to committing lists, returning count of number moved. |
960 | * Note called with i_lock held. | 963 | * Note called with i_lock held. |
961 | */ | 964 | */ |
962 | static int filelayout_scan_commit_lists(struct inode *inode, int max) | 965 | static int filelayout_scan_commit_lists(struct inode *inode, int max, |
966 | spinlock_t *lock) | ||
963 | { | 967 | { |
964 | struct pnfs_layout_segment *lseg; | 968 | struct pnfs_layout_segment *lseg; |
965 | struct nfs4_filelayout_segment *fl; | 969 | struct nfs4_filelayout_segment *fl; |
@@ -972,7 +976,8 @@ static int filelayout_scan_commit_lists(struct inode *inode, int max) | |||
972 | if (fl->commit_through_mds) | 976 | if (fl->commit_through_mds) |
973 | goto out_done; | 977 | goto out_done; |
974 | for (i = 0; i < fl->number_of_buckets && max != 0; i++) { | 978 | for (i = 0; i < fl->number_of_buckets && max != 0; i++) { |
975 | cnt = filelayout_scan_ds_commit_list(&fl->commit_buckets[i], max); | 979 | cnt = filelayout_scan_ds_commit_list(&fl->commit_buckets[i], |
980 | max, lock); | ||
976 | max -= cnt; | 981 | max -= cnt; |
977 | rv += cnt; | 982 | rv += cnt; |
978 | } | 983 | } |