lkml.org 
[lkml]   [2011]   [Sep]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH] memcg: Fix race condition in memcg_check_events() with this_cpu usage
    From
    Date
    From: Steven Rostedt <srostedt@redhat.com>

    The code in memcg_check_events() calls this_cpu_read() on
    different variables without disabling preemption, and can cause
    the calculations to be done from two different CPU variables.

    Disable preemption throughout the check to keep apples and oranges
    from becoming a mixed drink.

    [ Added this_cpu to __this_cpu conversion by Johannes ]

    Cc: Greg Thelen <gthelen@google.com>
    Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
    Cc: Balbir Singh <balbir@linux.vnet.ibm.com>
    Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Christoph Lameter <cl@linux.com>
    Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
    Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
    Link: http://lkml.kernel.org/r/20110919212641.015320989@goodmis.org
    ---
    mm/memcontrol.c | 10 ++++++----
    1 files changed, 6 insertions(+), 4 deletions(-)

    diff --git a/mm/memcontrol.c b/mm/memcontrol.c
    index 3508777..f823fc8 100644
    --- a/mm/memcontrol.c
    +++ b/mm/memcontrol.c
    @@ -683,8 +683,8 @@ static bool __memcg_event_check(struct mem_cgroup *mem, int target)
    {
    unsigned long val, next;

    - val = this_cpu_read(mem->stat->events[MEM_CGROUP_EVENTS_COUNT]);
    - next = this_cpu_read(mem->stat->targets[target]);
    + val = __this_cpu_read(mem->stat->events[MEM_CGROUP_EVENTS_COUNT]);
    + next = __this_cpu_read(mem->stat->targets[target]);
    /* from time_after() in jiffies.h */
    return ((long)next - (long)val < 0);
    }
    @@ -693,7 +693,7 @@ static void __mem_cgroup_target_update(struct mem_cgroup *mem, int target)
    {
    unsigned long val, next;

    - val = this_cpu_read(mem->stat->events[MEM_CGROUP_EVENTS_COUNT]);
    + val = __this_cpu_read(mem->stat->events[MEM_CGROUP_EVENTS_COUNT]);

    switch (target) {
    case MEM_CGROUP_TARGET_THRESH:
    @@ -709,7 +709,7 @@ static void __mem_cgroup_target_update(struct mem_cgroup *mem, int target)
    return;
    }

    - this_cpu_write(mem->stat->targets[target], next);
    + __this_cpu_write(mem->stat->targets[target], next);
    }

    /*
    @@ -718,6 +718,7 @@ static void __mem_cgroup_target_update(struct mem_cgroup *mem, int target)
    */
    static void memcg_check_events(struct mem_cgroup *mem, struct page *page)
    {
    + preempt_disable();
    /* threshold event is triggered in finer grain than soft limit */
    if (unlikely(__memcg_event_check(mem, MEM_CGROUP_TARGET_THRESH))) {
    mem_cgroup_threshold(mem);
    @@ -737,6 +738,7 @@ static void memcg_check_events(struct mem_cgroup *mem, struct page *page)
    }
    #endif
    }
    + preempt_enable();
    }

    static struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont)
    --
    1.7.3.4




    \
     
     \ /
      Last update: 2011-09-24 02:57    [W:5.603 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site