--- fs/ext4/inode.c | 24 ++++++++++++++++++++++++ mm/page_alloc.c | 4 +++- 2 files changed, 27 insertions(+), 1 deletion(-) Index: linux-2.6.28.10/fs/ext4/inode.c =================================================================== --- linux-2.6.28.10.orig/fs/ext4/inode.c 2010-03-03 15:29:23.000000000 +0100 +++ linux-2.6.28.10/fs/ext4/inode.c 2010-03-03 15:53:20.000000000 +0100 @@ -1335,6 +1335,7 @@ static int ext4_write_begin(struct file struct page *page; pgoff_t index; unsigned from, to; + int grab_cache_page_retries = 3; index = pos >> PAGE_CACHE_SHIFT; from = pos & (PAGE_CACHE_SIZE - 1); @@ -1354,6 +1355,17 @@ retry: page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { ext4_journal_stop(handle); + + /* retry to get memory because the reason for OOM could be + * AOP_FLAG_NOFS! */ + if (grab_cache_page_retries) { + printk(KERN_DEBUG "%s: retrying " + "grab_cache_page_write_begin()\n", __func__); + grab_cache_page_retries--; + schedule_timeout_uninterruptible(1); + goto retry; + } + ret = -ENOMEM; goto out; } @@ -2584,6 +2596,7 @@ static int ext4_da_write_begin(struct fi unsigned from, to; struct inode *inode = mapping->host; handle_t *handle; + int grab_cache_page_retries = 3; index = pos >> PAGE_CACHE_SHIFT; from = pos & (PAGE_CACHE_SIZE - 1); @@ -2614,6 +2627,17 @@ retry: page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { ext4_journal_stop(handle); + + /* retry to get memory because the reason for OOM could be + * AOP_FLAG_NOFS! */ + if (grab_cache_page_retries) { + printk(KERN_DEBUG "%s: retrying " + "grab_cache_page_write_begin()\n", __func__); + grab_cache_page_retries--; + schedule_timeout_uninterruptible(1); + goto retry; + } + ret = -ENOMEM; goto out; } Index: linux-2.6.28.10/mm/page_alloc.c =================================================================== --- linux-2.6.28.10.orig/mm/page_alloc.c 2010-03-03 15:52:18.000000000 +0100 +++ linux-2.6.28.10/mm/page_alloc.c 2010-03-03 15:52:22.000000000 +0100 @@ -1476,6 +1476,7 @@ __alloc_pages_internal(gfp_t gfp_mask, u int alloc_flags; unsigned long did_some_progress; unsigned long pages_reclaimed = 0; + int retries = 3; might_sleep_if(wait); @@ -1659,8 +1660,9 @@ nofail_alloc: if (gfp_mask & __GFP_NOFAIL) do_retry = 1; } - if (do_retry) { + if (do_retry && retries) { congestion_wait(WRITE, HZ/50); + retries--; goto rebalance; }