diff options
author | Mel Gorman <mgorman@suse.de> | 2012-07-31 19:44:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:42:45 -0400 |
commit | b37f1dd0f543d9714f96c2f9b9f74f7bdfdfdf31 (patch) | |
tree | 4d01913bd950d60c65605cd14e0ff88b74f5f716 | |
parent | 5091b74a95d447e34530e713a8971450a45498b3 (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.h | 10 | ||||
-rw-r--r-- | include/linux/mm_types.h | 2 | ||||
-rw-r--r-- | include/trace/events/gfpflags.h | 1 | ||||
-rw-r--r-- | mm/page_alloc.c | 22 | ||||
-rw-r--r-- | mm/slab.c | 2 |
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 | ||
2308 | bool gfp_pfmemalloc_allowed(gfp_t gfp_mask) | 2306 | bool 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 | ||
2313 | static inline struct page * | 2311 | static inline struct page * |
@@ -2498,12 +2496,12 @@ nopage: | |||
2498 | return page; | 2496 | return page; |
2499 | got_pg: | 2497 | got_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); |
@@ -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 | ||