summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2013-10-31 16:34:13 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-10-31 16:58:13 -0700
commit3168ecbe1c04ec3feb7cb42388a17d7f047fe1a2 (patch)
treeb8e0a03d787c2219b1d1fd833193de7abc59442e
parent12aee278b50c4a94a93fa0b4d201ae35d792c696 (diff)
mm: memcg: use proper memcg in limit bypass
Commit 84235de394d9 ("fs: buffer: move allocation failure loop into the allocator") allowed __GFP_NOFAIL allocations to bypass the limit if they fail to reclaim enough memory for the charge. But because the main test case was on a 3.2-based system, the patch missed the fact that on newer kernels the charge function needs to return root_mem_cgroup when bypassing the limit, and not NULL. This will corrupt whatever memory is at NULL + percpu pointer offset. Fix this quickly before problems are reported. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Acked-by: Michal Hocko <mhocko@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/memcontrol.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 497ec33ff22..623d5c8bb1e 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2765,10 +2765,10 @@ done:
*ptr = memcg;
return 0;
nomem:
- *ptr = NULL;
- if (gfp_mask & __GFP_NOFAIL)
- return 0;
- return -ENOMEM;
+ if (!(gfp_mask & __GFP_NOFAIL)) {
+ *ptr = NULL;
+ return -ENOMEM;
+ }
bypass:
*ptr = root_mem_cgroup;
return -EINTR;