From: Trond Myklebust With the following patch I'm able to get good interactive response even when running a 256-thread iozone session over NFSv3 + X +... (as opposed to simply crashing due to OOM). It contains the following elements: - Add missing unstable write accounting in sync_inodes_sb() - Add missing unstable write accounting in wakeup_bdflush(). - Decrement nr_unstable only when the COMMIT RPC call is done (rather then doing so when we schedule the RPC call). This ensures that we do try to wait for completion. - It is better to do too many rather than too *few* writes. Don't overestimate how many pages we wrote out in nfs_writepages(). fs/fs-writeback.c | 3 ++- fs/nfs/write.c | 6 +++--- mm/page-writeback.c | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff -puN fs/fs-writeback.c~nfs-writeback-tweak fs/fs-writeback.c --- 25/fs/fs-writeback.c~nfs-writeback-tweak 2003-05-08 00:28:02.000000000 -0700 +++ 25-akpm/fs/fs-writeback.c 2003-05-08 00:28:02.000000000 -0700 @@ -367,7 +367,8 @@ void sync_inodes_sb(struct super_block * }; get_page_state(&ps); - wbc.nr_to_write = ps.nr_dirty + ps.nr_dirty / 4; + wbc.nr_to_write = ps.nr_dirty + ps.nr_unstable + + (ps.nr_dirty + ps.nr_unstable) / 4; spin_lock(&inode_lock); sync_sb_inodes(sb, &wbc); spin_unlock(&inode_lock); diff -puN fs/nfs/write.c~nfs-writeback-tweak fs/nfs/write.c --- 25/fs/nfs/write.c~nfs-writeback-tweak 2003-05-08 00:28:02.000000000 -0700 +++ 25-akpm/fs/nfs/write.c 2003-05-08 00:28:02.000000000 -0700 @@ -280,8 +280,6 @@ nfs_writepages(struct address_space *map err = nfs_wb_all(inode); } else nfs_commit_file(inode, NULL, 0, 0, 0); - /* Avoid races. Tell upstream we've done all we were told to do */ - wbc->nr_to_write = 0; out: return err; } @@ -490,7 +488,6 @@ nfs_scan_commit(struct inode *inode, str int res; res = nfs_scan_list(&nfsi->commit, dst, file, idx_start, npages); nfsi->ncommit -= res; - sub_page_state(nr_unstable,res); if ((nfsi->ncommit == 0) != list_empty(&nfsi->commit)) printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n"); return res; @@ -1009,6 +1006,7 @@ nfs_commit_done(struct rpc_task *task) { struct nfs_write_data *data = (struct nfs_write_data *)task->tk_calldata; struct nfs_page *req; + int res = 0; dprintk("NFS: %4d nfs_commit_done (status %d)\n", task->tk_pid, task->tk_status); @@ -1043,7 +1041,9 @@ nfs_commit_done(struct rpc_task *task) nfs_mark_request_dirty(req); next: nfs_unlock_request(req); + res++; } + sub_page_state(nr_unstable,res); } #endif diff -puN mm/page-writeback.c~nfs-writeback-tweak mm/page-writeback.c --- 25/mm/page-writeback.c~nfs-writeback-tweak 2003-05-08 00:28:02.000000000 -0700 +++ 25-akpm/mm/page-writeback.c 2003-05-08 00:28:02.000000000 -0700 @@ -270,7 +270,7 @@ int wakeup_bdflush(long nr_pages) struct page_state ps; get_page_state(&ps); - nr_pages = ps.nr_dirty; + nr_pages = ps.nr_dirty + ps.nr_unstable; } return pdflush_operation(background_writeout, nr_pages); } _