[lkml]   [2010]   [Jan]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[PATCH 22/52] cgroups: fix 2.6.32 regression causing BUG_ON() in cgroup_diput()
    From: Dave Anderson <>

    commit bd4f490a079730aadfaf9a728303ea0135c01945 upstream.

    The LTP cgroup test suite generates a "kernel BUG at kernel/cgroup.c:790!"
    here in cgroup_diput():

    * if we're getting rid of the cgroup, refcount should ensure
    * that there are no pidlists left.

    The cgroup pidlist rework in 2.6.32 generates the BUG_ON, which is caused
    when pidlist_array_load() calls cgroup_pidlist_find():

    (1) if a matching cgroup_pidlist is found, it down_write's the mutex of the
    pre-existing cgroup_pidlist, and increments its use_count.
    (2) if no matching cgroup_pidlist is found, then a new one is allocated, it
    down_write's its mutex, and the use_count is set to 0.
    (3) the matching, or new, cgroup_pidlist gets returned back to pidlist_array_load(),
    which increments its use_count -- regardless whether new or pre-existing --
    and up_write's the mutex.

    So if a matching list is ever encountered by cgroup_pidlist_find() during
    the life of a cgroup directory, it results in an inflated use_count value,
    preventing it from ever getting released by cgroup_release_pid_array().
    Then if the directory is subsequently removed, cgroup_diput() hits the
    BUG_ON() when it finds that the directory's cgroup is still populated with
    a pidlist.

    The patch simply removes the use_count increment when a matching pidlist
    is found by cgroup_pidlist_find(), because it gets bumped by the calling
    pidlist_array_load() function while still protected by the list's mutex.

    Signed-off-by: Dave Anderson <>
    Reviewed-by: Li Zefan <>
    Acked-by: Ben Blum <>
    Cc: Paul Menage <>
    Signed-off-by: Andrew Morton <>
    Signed-off-by: Linus Torvalds <>
    Signed-off-by: Greg Kroah-Hartman <>
    kernel/cgroup.c | 1 -
    1 files changed, 0 insertions(+), 1 deletions(-)

    diff --git a/kernel/cgroup.c b/kernel/cgroup.c
    index 0249f4b..1fbcc74 100644
    --- a/kernel/cgroup.c
    +++ b/kernel/cgroup.c
    @@ -2468,7 +2468,6 @@ static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp,
    /* make sure l doesn't vanish out from under us */
    - l->use_count++;
    return l;

     \ /
      Last update: 2010-01-14 23:33    [W:0.028 / U:0.640 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site