aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMel Gorman <mgorman@suse.de>2012-07-31 19:44:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:42:45 -0400
commitb37f1dd0f543d9714f96c2f9b9f74f7bdfdfdf31 (patch)
tree4d01913bd950d60c65605cd14e0ff88b74f5f716
parent5091b74a95d447e34530e713a8971450a45498b3 (diff)
mm: introduce __GFP_MEMALLOC to allow access to emergency reserves
__GFP_MEMALLOC will allow the allocation to disregard the watermarks, much like PF_MEMALLOC. It allows one to pass along the memalloc state in object related allocation flags as opposed to task related flags, such as sk->sk_allocation. This removes the need for ALLOC_PFMEMALLOC as callers using __GFP_MEMALLOC can get the ALLOC_NO_WATERMARK flag which is now enough to identify allocations related to page reclaim. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Mel Gorman <mgorman@suse.de> Cc: David Miller <davem@davemloft.net> Cc: Neil Brown <neilb@suse.de> Cc: Mike Christie <michaelc@cs.wisc.edu> Cc: Eric B Munson <emunson@mgebm.net> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> Cc: Mel Gorman <mgorman@suse.de> Cc: Christoph Lameter <cl@linux.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/gfp.h10
-rw-r--r--include/linux/mm_types.h2
-rw-r--r--include/trace/events/gfpflags.h1
-rw-r--r--mm/page_alloc.c22
-rw-r--r--mm/slab.c2
5 files changed, 21 insertions, 16 deletions
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 1e49be49d324..cbd7400e5862 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -23,6 +23,7 @@ struct vm_area_struct;
23#define ___GFP_REPEAT 0x400u 23#define ___GFP_REPEAT 0x400u
24#define ___GFP_NOFAIL 0x800u 24#define ___GFP_NOFAIL 0x800u
25#define ___GFP_NORETRY 0x1000u 25#define ___GFP_NORETRY 0x1000u
26#define ___GFP_MEMALLOC 0x2000u
26#define ___GFP_COMP 0x4000u 27#define ___GFP_COMP 0x4000u
27#define ___GFP_ZERO 0x8000u 28#define ___GFP_ZERO 0x8000u
28#define ___GFP_NOMEMALLOC 0x10000u 29#define ___GFP_NOMEMALLOC 0x10000u
@@ -76,9 +77,14 @@ struct vm_area_struct;
76#define __GFP_REPEAT ((__force gfp_t)___GFP_REPEAT) /* See above */ 77#define __GFP_REPEAT ((__force gfp_t)___GFP_REPEAT) /* See above */
77#define __GFP_NOFAIL ((__force gfp_t)___GFP_NOFAIL) /* See above */ 78#define __GFP_NOFAIL ((__force gfp_t)___GFP_NOFAIL) /* See above */
78#define __GFP_NORETRY ((__force gfp_t)___GFP_NORETRY) /* See above */ 79#define __GFP_NORETRY ((__force gfp_t)___GFP_NORETRY) /* See above */
80#define __GFP_MEMALLOC ((__force gfp_t)___GFP_MEMALLOC)/* Allow access to emergency reserves */
79#define __GFP_COMP ((__force gfp_t)___GFP_COMP) /* Add compound page metadata */ 81#define __GFP_COMP ((__force gfp_t)___GFP_COMP) /* Add compound page metadata */
80#define __GFP_ZERO ((__force gfp_t)___GFP_ZERO) /* Return zeroed page on success */ 82#define __GFP_ZERO ((__force gfp_t)___GFP_ZERO) /* Return zeroed page on success */
81#define __GFP_NOMEMALLOC ((__force gfp_t)___GFP_NOMEMALLOC) /* Don't use emergency reserves */ 83#define __GFP_NOMEMALLOC ((__force gfp_t)___GFP_NOMEMALLOC) /* Don't use emergency reserves.
84 * This takes precedence over the
85 * __GFP_MEMALLOC flag if both are
86 * set
87 */
82#define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL) /* Enforce hardwall cpuset memory allocs */ 88#define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL) /* Enforce hardwall cpuset memory allocs */
83#define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)/* No fallback, no policies */ 89#define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)/* No fallback, no policies */
84#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */ 90#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */
@@ -129,7 +135,7 @@ struct vm_area_struct;
129/* Control page allocator reclaim behavior */ 135/* Control page allocator reclaim behavior */
130#define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\ 136#define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\
131 __GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|\ 137 __GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|\
132 __GFP_NORETRY|__GFP_NOMEMALLOC) 138 __GFP_NORETRY|__GFP_MEMALLOC|__GFP_NOMEMALLOC)
133 139
134/* Control slab gfp mask during early boot */ 140/* Control slab gfp mask during early boot */
135#define GFP_BOOT_MASK (__GFP_BITS_MASK & ~(__GFP_WAIT|__GFP_IO|__GFP_FS)) 141#define GFP_BOOT_MASK (__GFP_BITS_MASK & ~(__GFP_WAIT|__GFP_IO|__GFP_FS))
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 375e79eb009b..bf7867200b95 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -55,7 +55,7 @@ struct page {
55 pgoff_t index; /* Our offset within mapping. */ 55 pgoff_t index; /* Our offset within mapping. */
56 void *freelist; /* slub/slob first free object */ 56 void *freelist; /* slub/slob first free object */
57 bool pfmemalloc; /* If set by the page allocator, 57 bool pfmemalloc; /* If set by the page allocator,
58 * ALLOC_PFMEMALLOC was set 58 * ALLOC_NO_WATERMARKS was set
59 * and the low watermark was not 59 * and the low watermark was not
60 * met implying that the system 60 * met implying that the system
61 * is under some pressure. The 61 * is under some pressure. The
diff --git a/include/trace/events/gfpflags.h b/include/trace/events/gfpflags.h
index 9fe3a36646e9..d6fd8e5b14b7 100644
--- a/include/trace/events/gfpflags.h
+++ b/include/trace/events/gfpflags.h
@@ -30,6 +30,7 @@
30 {(unsigned long)__GFP_COMP, "GFP_COMP"}, \ 30 {(unsigned long)__GFP_COMP, "GFP_COMP"}, \
31 {(unsigned long)__GFP_ZERO, "GFP_ZERO"}, \ 31 {(unsigned long)__GFP_ZERO, "GFP_ZERO"}, \
32 {(unsigned long)__GFP_NOMEMALLOC, "GFP_NOMEMALLOC"}, \ 32 {(unsigned long)__GFP_NOMEMALLOC, "GFP_NOMEMALLOC"}, \
33 {(unsigned long)__GFP_MEMALLOC, "GFP_MEMALLOC"}, \
33 {(unsigned long)__GFP_HARDWALL, "GFP_HARDWALL"}, \ 34 {(unsigned long)__GFP_HARDWALL, "GFP_HARDWALL"}, \
34 {(unsigned long)__GFP_THISNODE, "GFP_THISNODE"}, \ 35 {(unsigned long)__GFP_THISNODE, "GFP_THISNODE"}, \
35 {(unsigned long)__GFP_RECLAIMABLE, "GFP_RECLAIMABLE"}, \ 36 {(unsigned long)__GFP_RECLAIMABLE, "GFP_RECLAIMABLE"}, \
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 38e5be65f24e..8f65abeb9ad6 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1513,7 +1513,6 @@ failed:
1513#define ALLOC_HARDER 0x10 /* try to alloc harder */ 1513#define ALLOC_HARDER 0x10 /* try to alloc harder */
1514#define ALLOC_HIGH 0x20 /* __GFP_HIGH set */ 1514#define ALLOC_HIGH 0x20 /* __GFP_HIGH set */
1515#define ALLOC_CPUSET 0x40 /* check for correct cpuset */ 1515#define ALLOC_CPUSET 0x40 /* check for correct cpuset */
1516#define ALLOC_PFMEMALLOC 0x80 /* Caller has PF_MEMALLOC set */
1517 1516
1518#ifdef CONFIG_FAIL_PAGE_ALLOC 1517#ifdef CONFIG_FAIL_PAGE_ALLOC
1519 1518
@@ -2294,11 +2293,10 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
2294 } else if (unlikely(rt_task(current)) && !in_interrupt()) 2293 } else if (unlikely(rt_task(current)) && !in_interrupt())
2295 alloc_flags |= ALLOC_HARDER; 2294 alloc_flags |= ALLOC_HARDER;
2296 2295
2297 if ((current->flags & PF_MEMALLOC) || 2296 if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) {
2298 unlikely(test_thread_flag(TIF_MEMDIE))) { 2297 if (gfp_mask & __GFP_MEMALLOC)
2299 alloc_flags |= ALLOC_PFMEMALLOC; 2298 alloc_flags |= ALLOC_NO_WATERMARKS;
2300 2299 else if (likely(!(gfp_mask & __GFP_NOMEMALLOC)) && !in_interrupt())
2301 if (likely(!(gfp_mask & __GFP_NOMEMALLOC)) && !in_interrupt())
2302 alloc_flags |= ALLOC_NO_WATERMARKS; 2300 alloc_flags |= ALLOC_NO_WATERMARKS;
2303 } 2301 }
2304 2302
@@ -2307,7 +2305,7 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
2307 2305
2308bool gfp_pfmemalloc_allowed(gfp_t gfp_mask) 2306bool gfp_pfmemalloc_allowed(gfp_t gfp_mask)
2309{ 2307{
2310 return !!(gfp_to_alloc_flags(gfp_mask) & ALLOC_PFMEMALLOC); 2308 return !!(gfp_to_alloc_flags(gfp_mask) & ALLOC_NO_WATERMARKS);
2311} 2309}
2312 2310
2313static inline struct page * 2311static inline struct page *
@@ -2498,12 +2496,12 @@ nopage:
2498 return page; 2496 return page;
2499got_pg: 2497got_pg:
2500 /* 2498 /*
2501 * page->pfmemalloc is set when the caller had PFMEMALLOC set or is 2499 * page->pfmemalloc is set when the caller had PFMEMALLOC set, is
2502 * been OOM killed. The expectation is that the caller is taking 2500 * been OOM killed or specified __GFP_MEMALLOC. The expectation is
2503 * steps that will free more memory. The caller should avoid the 2501 * that the caller is taking steps that will free more memory. The
2504 * page being used for !PFMEMALLOC purposes. 2502 * caller should avoid the page being used for !PFMEMALLOC purposes.
2505 */ 2503 */
2506 page->pfmemalloc = !!(alloc_flags & ALLOC_PFMEMALLOC); 2504 page->pfmemalloc = !!(alloc_flags & ALLOC_NO_WATERMARKS);
2507 2505
2508 if (kmemcheck_enabled) 2506 if (kmemcheck_enabled)
2509 kmemcheck_pagealloc_alloc(page, order, gfp_mask); 2507 kmemcheck_pagealloc_alloc(page, order, gfp_mask);
diff --git a/mm/slab.c b/mm/slab.c
index 55d84a22ad96..77be18dab73c 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1884,7 +1884,7 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
1884 return NULL; 1884 return NULL;
1885 } 1885 }
1886 1886
1887 /* Record if ALLOC_PFMEMALLOC was set when allocating the slab */ 1887 /* Record if ALLOC_NO_WATERMARKS was set when allocating the slab */
1888 if (unlikely(page->pfmemalloc)) 1888 if (unlikely(page->pfmemalloc))
1889 pfmemalloc_active = true; 1889 pfmemalloc_active = true;
1890 1890