diff -Nurp --exclude-from=/home/mcd/.dontdiff linux-2.6.11-mm4/mm/page_alloc.c linux-2.6.11-mm4+fix-__alloc_pages/mm/page_alloc.c --- linux-2.6.11-mm4/mm/page_alloc.c 2005-03-16 16:07:49.179230440 -0800 +++ linux-2.6.11-mm4+fix-__alloc_pages/mm/page_alloc.c 2005-03-16 16:09:54.019251872 -0800 @@ -867,13 +867,14 @@ __alloc_pages(unsigned int gfp_mask, uns const int wait = gfp_mask & __GFP_WAIT; struct zone **zones, *z; struct page *page; - struct reclaim_state reclaim_state; + struct reclaim_state reclaim_state = { .reclaimed_slab = 0 }; struct task_struct *p = current; int i; int classzone_idx; int do_retry; int can_try_harder; int did_some_progress; + int is_memalloc = 0, has_reclaim_state = 0; might_sleep_if(wait); @@ -957,14 +958,22 @@ rebalance: cond_resched(); /* We now go into synchronous reclaim */ - p->flags |= PF_MEMALLOC; - reclaim_state.reclaimed_slab = 0; - p->reclaim_state = &reclaim_state; + if (p->flags & PF_MEMALLOC) + is_memalloc = 1; + else + p->flags |= PF_MEMALLOC; + + if (p->reclaim_state) + has_reclaim_state = 1; + else + p->reclaim_state = &reclaim_state; did_some_progress = try_to_free_pages(zones, gfp_mask, order); - p->reclaim_state = NULL; - p->flags &= ~PF_MEMALLOC; + if (!has_reclaim_state) + p->reclaim_state = NULL; + if (!is_memalloc) + p->flags &= ~PF_MEMALLOC; cond_resched();