|
@@ -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;
|
|
|
}
|
|
|
|