lkml.org 
[lkml]   [2013]   [Jul]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[029/141] mm: memcg: remove incorrect VM_BUG_ON for swap cache pages in uncharge
    3.6.11.6 stable review patch.
    If anyone has any objections, please let me know.

    ------------------

    From: Johannes Weiner <hannes@cmpxchg.org>

    [ Upstream commit 28ccddf7952c496df2a51ce5aee4f2a058a98bab ]

    Commit 0c59b89c81ea ("mm: memcg: push down PageSwapCache check into
    uncharge entry functions") added a VM_BUG_ON() on PageSwapCache in the
    uncharge path after checking that page flag once, assuming that the
    state is stable in all paths, but this is not the case and the condition
    triggers in user environments. An uncharge after the last page table
    reference to the page goes away can race with reclaim adding the page to
    swap cache.

    Swap cache pages are usually uncharged when they are freed after
    swapout, from a path that also handles swap usage accounting and memcg
    lifetime management. However, since the last page table reference is
    gone and thus no references to the swap slot left, the swap slot will be
    freed shortly when reclaim attempts to write the page to disk. The
    whole swap accounting is not even necessary.

    So while the race condition for which this VM_BUG_ON was added is real
    and actually existed all along, there are no negative effects. Remove
    the VM_BUG_ON again.

    Reported-by: Heiko Carstens <heiko.carstens@de.ibm.com>
    Reported-by: Lingzhu Xiang <lxiang@redhat.com>
    Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
    Acked-by: Hugh Dickins <hughd@google.com>
    Acked-by: Michal Hocko <mhocko@suse.cz>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
    ---
    mm/memcontrol.c | 14 ++++++++++++--
    1 file changed, 12 insertions(+), 2 deletions(-)

    diff --git a/mm/memcontrol.c b/mm/memcontrol.c
    index a6e2f81..a2c673a 100644
    --- a/mm/memcontrol.c
    +++ b/mm/memcontrol.c
    @@ -3030,8 +3030,6 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype,
    if (mem_cgroup_disabled())
    return NULL;

    - VM_BUG_ON(PageSwapCache(page));
    -
    if (PageTransHuge(page)) {
    nr_pages <<= compound_order(page);
    VM_BUG_ON(!PageTransHuge(page));
    @@ -3127,6 +3125,18 @@ void mem_cgroup_uncharge_page(struct page *page)
    if (page_mapped(page))
    return;
    VM_BUG_ON(page->mapping && !PageAnon(page));
    + /*
    + * If the page is in swap cache, uncharge should be deferred
    + * to the swap path, which also properly accounts swap usage
    + * and handles memcg lifetime.
    + *
    + * Note that this check is not stable and reclaim may add the
    + * page to swap cache at any time after this. However, if the
    + * page is not in swap cache by the time page->mapcount hits
    + * 0, there won't be any page table references to the swap
    + * slot, and reclaim will free it and not actually write the
    + * page to disk.
    + */
    if (PageSwapCache(page))
    return;
    __mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_ANON, false);
    --
    1.7.10.4



    \
     
     \ /
      Last update: 2013-07-04 00:21    [W:4.312 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site