diff options
Diffstat (limited to 'mm/page_alloc.c')
| -rw-r--r-- | mm/page_alloc.c | 27 | 
1 files changed, 22 insertions, 5 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6a29ed8e6e6..38e5be65f24 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1513,6 +1513,7 @@ failed:  #define ALLOC_HARDER		0x10 /* try to alloc harder */  #define ALLOC_HIGH		0x20 /* __GFP_HIGH set */  #define ALLOC_CPUSET		0x40 /* check for correct cpuset */ +#define ALLOC_PFMEMALLOC	0x80 /* Caller has PF_MEMALLOC set */  #ifdef CONFIG_FAIL_PAGE_ALLOC @@ -2293,16 +2294,22 @@ gfp_to_alloc_flags(gfp_t gfp_mask)  	} else if (unlikely(rt_task(current)) && !in_interrupt())  		alloc_flags |= ALLOC_HARDER; -	if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) { -		if (!in_interrupt() && -		    ((current->flags & PF_MEMALLOC) || -		     unlikely(test_thread_flag(TIF_MEMDIE)))) +	if ((current->flags & PF_MEMALLOC) || +			unlikely(test_thread_flag(TIF_MEMDIE))) { +		alloc_flags |= ALLOC_PFMEMALLOC; + +		if (likely(!(gfp_mask & __GFP_NOMEMALLOC)) && !in_interrupt())  			alloc_flags |= ALLOC_NO_WATERMARKS;  	}  	return alloc_flags;  } +bool gfp_pfmemalloc_allowed(gfp_t gfp_mask) +{ +	return !!(gfp_to_alloc_flags(gfp_mask) & ALLOC_PFMEMALLOC); +} +  static inline struct page *  __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,  	struct zonelist *zonelist, enum zone_type high_zoneidx, @@ -2490,10 +2497,18 @@ nopage:  	warn_alloc_failed(gfp_mask, order, NULL);  	return page;  got_pg: +	/* +	 * page->pfmemalloc is set when the caller had PFMEMALLOC set or is +	 * been OOM killed. The expectation is that the caller is taking +	 * steps that will free more memory. The caller should avoid the +	 * page being used for !PFMEMALLOC purposes. +	 */ +	page->pfmemalloc = !!(alloc_flags & ALLOC_PFMEMALLOC); +  	if (kmemcheck_enabled)  		kmemcheck_pagealloc_alloc(page, order, gfp_mask); -	return page; +	return page;  }  /* @@ -2544,6 +2559,8 @@ retry_cpuset:  		page = __alloc_pages_slowpath(gfp_mask, order,  				zonelist, high_zoneidx, nodemask,  				preferred_zone, migratetype); +	else +		page->pfmemalloc = false;  	trace_mm_page_alloc(page, order, gfp_mask, migratetype);  |