• G
    memcg: remove incorrect underflow check · 6920a1bd
    Greg Thelen 提交于
    When a memcg is deleted mem_cgroup_reparent_charges() moves charged
    memory to the parent memcg.  As of v3.11-9444-g3ea67d06 "memcg: add per
    cgroup writeback pages accounting" there's bad pointer read.  The goal
    was to check for counter underflow.  The counter is a per cpu counter
    and there are two problems with the code:
    
     (1) per cpu access function isn't used, instead a naked pointer is used
         which easily causes oops.
     (2) the check doesn't sum all cpus
    
    Test:
      $ cd /sys/fs/cgroup/memory
      $ mkdir x
      $ echo 3 > /proc/sys/vm/drop_caches
      $ (echo $BASHPID >> x/tasks && exec cat) &
      [1] 7154
      $ grep ^mapped x/memory.stat
      mapped_file 53248
      $ echo 7154 > tasks
      $ rmdir x
      <OOPS>
    
    The fix is to remove the check.  It's currently dangerous and isn't
    worth fixing it to use something expensive, such as
    percpu_counter_sum(), for each reparented page.  __this_cpu_read() isn't
    enough to fix this because there's no guarantees of the current cpus
    count.  The only guarantees is that the sum of all per-cpu counter is >=
    nr_pages.
    
    Fixes: 3ea67d06 ("memcg: add per cgroup writeback pages accounting")
    Reported-and-tested-by: NFlavio Leitner <fbl@redhat.com>
    Signed-off-by: NGreg Thelen <gthelen@google.com>
    Reviewed-by: NSha Zhengju <handai.szj@taobao.com>
    Acked-by: NJohannes Weiner <hannes@cmpxchg.org>
    Signed-off-by: NHugh Dickins <hughd@google.com>
    Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
    6920a1bd
memcontrol.c 186.2 KB