summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2013-11-01 00:34:13 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-01 00:58:13 +0100
commit3168ecbe1c04ec3feb7cb42388a17d7f047fe1a2 (patch)
treeb8e0a03d787c2219b1d1fd833193de7abc59442e
parentMerge branch 'akpm' (fixes from Andrew Morton) (diff)
downloadlinux-3168ecbe1c04ec3feb7cb42388a17d7f047fe1a2.tar.xz
linux-3168ecbe1c04ec3feb7cb42388a17d7f047fe1a2.zip
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 497ec33ff22d..623d5c8bb1e1 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;