diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2007-03-16 13:38:26 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-16 19:25:05 -0700 |
commit | 89a09141df6ac1c3821fbe44ca8384eb37692965 (patch) | |
tree | ccb21055fca86ac2657b3262ac37eb3e5c44bea0 /include/linux | |
parent | b74a2f0913694556a027795d2954d30523fac4c5 (diff) | |
download | op-kernel-dev-89a09141df6ac1c3821fbe44ca8384eb37692965.zip op-kernel-dev-89a09141df6ac1c3821fbe44ca8384eb37692965.tar.gz |
[PATCH] nfs: fix congestion control
The current NFS client congestion logic is severly broken, it marks the
backing device congested during each nfs_writepages() call but doesn't
mirror this in nfs_writepage() which makes for deadlocks. Also it
implements its own waitqueue.
Replace this by a more regular congestion implementation that puts a cap on
the number of active writeback pages and uses the bdi congestion waitqueue.
Also always use an interruptible wait since it makes sense to be able to
SIGKILL the process even for mounts without 'intr'.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: Christoph Lameter <clameter@engr.sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/backing-dev.h | 1 | ||||
-rw-r--r-- | include/linux/nfs_fs.h | 1 | ||||
-rw-r--r-- | include/linux/nfs_fs_sb.h | 1 |
3 files changed, 3 insertions, 0 deletions
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index 7011d625..f2542c2 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -93,6 +93,7 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi) void clear_bdi_congested(struct backing_dev_info *bdi, int rw); void set_bdi_congested(struct backing_dev_info *bdi, int rw); long congestion_wait(int rw, long timeout); +long congestion_wait_interruptible(int rw, long timeout); void congestion_end(int rw); #define bdi_cap_writeback_dirty(bdi) \ diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 47aaa2c..e9ae0c6 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -415,6 +415,7 @@ extern void nfs_complete_unlink(struct dentry *); /* * linux/fs/nfs/write.c */ +extern int nfs_congestion_kb; extern int nfs_writepage(struct page *page, struct writeback_control *wbc); extern int nfs_writepages(struct address_space *, struct writeback_control *); extern int nfs_flush_incompatible(struct file *file, struct page *page); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 95796e6..c95d5e6 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -82,6 +82,7 @@ struct nfs_server { struct rpc_clnt * client_acl; /* ACL RPC client handle */ struct nfs_iostats * io_stats; /* I/O statistics */ struct backing_dev_info backing_dev_info; + atomic_t writeback; /* number of writeback pages */ int flags; /* various flags */ unsigned int caps; /* server capabilities */ unsigned int rsize; /* read size */ |