From f33944edff15a55bfad3af9165bcaafe5775076e Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Thu, 9 Sep 2010 16:38:18 -0700 Subject: [PATCH] --- yaml --- r: 210478 b: refs/heads/master c: 9ee493ce0a60bf42c0f8fd0b0fe91df5704a1cbf h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/mm/page_alloc.c | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 39672d452802..121ef97cff1f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: aa45484031ddee09b06350ab8528bfe5b2c76d1c +refs/heads/master: 9ee493ce0a60bf42c0f8fd0b0fe91df5704a1cbf diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index b2d21e06d45d..a8cfa9cc6e86 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -1847,6 +1847,7 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order, struct page *page = NULL; struct reclaim_state reclaim_state; struct task_struct *p = current; + bool drained = false; cond_resched(); @@ -1865,14 +1866,25 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order, cond_resched(); - if (order != 0) - drain_all_pages(); + if (unlikely(!(*did_some_progress))) + return NULL; - if (likely(*did_some_progress)) - page = get_page_from_freelist(gfp_mask, nodemask, order, +retry: + page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, high_zoneidx, alloc_flags, preferred_zone, migratetype); + + /* + * If an allocation failed after direct reclaim, it could be because + * pages are pinned on the per-cpu lists. Drain them and try again + */ + if (!page && !drained) { + drain_all_pages(); + drained = true; + goto retry; + } + return page; }