fs/nfs/pagelist.c |    6 +++++-
 fs/nfs/write.c    |    9 +++++++++
 mm/page_alloc.c   |    9 +++++++--
 3 files changed, 21 insertions(+), 3 deletions(-)

diff -puN fs/nfs/write.c~nfs-more-oom-fix fs/nfs/write.c
--- 25/fs/nfs/write.c~nfs-more-oom-fix	Tue Feb 11 16:40:21 2003
+++ 25-akpm/fs/nfs/write.c	Tue Feb 11 16:42:31 2003
@@ -220,6 +220,10 @@ nfs_writepage_async(struct file *file, s
 
 /*
  * Write an mmapped page to the server.
+ *
+ * NFS is special.  It clears PF_MEMALLOC because that could cause page reclaim
+ * to use *all* memory writing pages to the server.  But we _must_ leave memory
+ * available for network Rx.
  */
 int
 nfs_writepage(struct page *page, struct writeback_control *wbc)
@@ -228,6 +232,10 @@ nfs_writepage(struct page *page, struct 
 	unsigned long end_index;
 	unsigned offset = PAGE_CACHE_SIZE;
 	int err = -EIO;
+	int flags_save;
+
+	flags_save = current->flags;
+	current->flags &= ~PF_MEMALLOC;
 
 	end_index = inode->i_size >> PAGE_CACHE_SHIFT;
 
@@ -258,6 +266,7 @@ nfs_writepage(struct page *page, struct 
 	unlock_kernel();
 out:
 	unlock_page(page);
+	current->flags = flags_save;
 	return err; 
 }
 
diff -puN fs/nfs/pagelist.c~nfs-more-oom-fix fs/nfs/pagelist.c
--- 25/fs/nfs/pagelist.c~nfs-more-oom-fix	Tue Feb 11 16:44:00 2003
+++ 25-akpm/fs/nfs/pagelist.c	Tue Feb 11 16:45:17 2003
@@ -31,11 +31,15 @@ spinlock_t nfs_wreq_lock = SPIN_LOCK_UNL
 static kmem_cache_t *nfs_page_cachep;
 static mempool_t *nfs_page_mempool;
 
+/*
+ * Use __GFP_HIGH here so that NFS can utilise _some_ of the page reserves.
+ * Important, because we've turned off PF_MEMALLOC in nfs_writepage().
+ */
 static inline struct nfs_page *
 nfs_page_alloc(void)
 {
 	struct nfs_page	*p;
-	p = mempool_alloc(nfs_page_mempool, SLAB_NOFS);
+	p = mempool_alloc(nfs_page_mempool, SLAB_NOFS|__GFP_HIGH);
 	if (p) {
 		memset(p, 0, sizeof(*p));
 		INIT_LIST_HEAD(&p->wb_list);
diff -puN mm/page_alloc.c~nfs-more-oom-fix mm/page_alloc.c
--- 25/mm/page_alloc.c~nfs-more-oom-fix	Tue Feb 11 16:45:22 2003
+++ 25-akpm/mm/page_alloc.c	Tue Feb 11 16:46:26 2003
@@ -568,7 +568,10 @@ __alloc_pages(unsigned int gfp_mask, uns
 	for (i = 0; zones[i] != NULL; i++)
 		wakeup_kswapd(zones[i]);
 
-	/* Go through the zonelist again, taking __GFP_HIGH into account */
+	/*
+	 * Go through the zonelist again, taking __GFP_HIGH and in_interrupt()
+	 * into account.
+	 */
 	min = 1UL << order;
 	for (i = 0; zones[i] != NULL; i++) {
 		unsigned long local_min;
@@ -576,7 +579,9 @@ __alloc_pages(unsigned int gfp_mask, uns
 
 		local_min = z->pages_min;
 		if (gfp_mask & __GFP_HIGH)
-			local_min >>= 2;
+			local_min >>= 1;
+		if (in_interrupt())
+			local_min >>= 1;
 		min += local_min;
 		if (z->free_pages >= min ||
 				(!wait && z->free_pages >= z->pages_high)) {

_