mm/memcontrol.c: fix the margin computation in mem_cgroup_margin()
authorLi RongQing <roy.qing.li@gmail.com>
Fri, 27 May 2016 21:27:43 +0000 (14:27 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 27 May 2016 21:49:37 +0000 (14:49 -0700)
mem_cgroup_margin() might return (memory.limit - memory_count) when the
memsw.limit is in excess.  This doesn't happen usually because we do not
allow excess on hard limits and (memory.limit <= memsw.limit), but
__GFP_NOFAIL charges can force the charge and cause the excess when no
memory is really swappable (swap is full or no anonymous memory is
left).

[mhocko@suse.com: rewrote changelog]
Link: http://lkml.kernel.org/r/20160525155122.GK20132@dhcp22.suse.cz
Link: http://lkml.kernel.org/r/1464068266-27736-1-git-send-email-roy.qing.li@gmail.com
Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
Acked-by: Vladimir Davydov <vdavydov@virtuozzo.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/memcontrol.c

index f6477a9dbe7ab42c98ff05bc4f2050d897eb6b0a..485c688a7fa8a1e17ff7c08d49e65b9604db281a 100644 (file)
@@ -1108,6 +1108,8 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg)
                limit = READ_ONCE(memcg->memsw.limit);
                if (count <= limit)
                        margin = min(margin, limit - count);
+               else
+                       margin = 0;
        }
 
        return margin;