From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755436AbaEFUVu (ORCPT ); Tue, 6 May 2014 16:21:50 -0400 Received: from mail-qg0-f43.google.com ([209.85.192.43]:64709 "EHLO mail-qg0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755146AbaEFUTo (ORCPT ); Tue, 6 May 2014 16:19:44 -0400 From: Tejun Heo To: lizefan@huawei.com Cc: cgroups@vger.kernel.org, linux-kernel@vger.kernel.org, Tejun Heo Subject: [PATCH 4/8] cgroup: move cgroup->kn->priv clearing to cgroup_rmdir() Date: Tue, 6 May 2014 16:19:30 -0400 Message-Id: <1399407574-21472-5-git-send-email-tj@kernel.org> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1399407574-21472-1-git-send-email-tj@kernel.org> References: <1399407574-21472-1-git-send-email-tj@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The ->priv field of a cgroup directory kernfs_node points back to the cgroup. This field is RCU cleared in cgroup_destroy_locked() for non-kernfs accesses from css_tryget_from_dir() and cgroupstats_build(). As these are only applicable to cgroups which finished creation successfully and fully initialized cgroups are always removed by cgroup_rmdir(), this can be safely moved to the end of cgroup_rmdir(). This will help simplifying cgroup locking and shouldn't introduce any behavior difference. Signed-off-by: Tejun Heo --- kernel/cgroup.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index f544e46..3118a63 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -4547,17 +4547,7 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) /* remove @cgrp directory along with the base files */ mutex_unlock(&cgroup_mutex); - - /* - * There are two control paths which try to determine cgroup from - * dentry without going through kernfs - cgroupstats_build() and - * css_tryget_from_dir(). Those are supported by RCU protecting - * clearing of cgrp->kn->priv backpointer, which should happen - * after all files under it have been removed. - */ kernfs_remove(cgrp->kn); /* @cgrp has an extra ref on its kn */ - RCU_INIT_POINTER(*(void __rcu __force **)&cgrp->kn->priv, NULL); - mutex_lock(&cgroup_mutex); return 0; @@ -4616,6 +4606,17 @@ static int cgroup_rmdir(struct kernfs_node *kn) mutex_unlock(&cgroup_tree_mutex); kernfs_unbreak_active_protection(kn); + + /* + * There are two control paths which try to determine cgroup from + * dentry without going through kernfs - cgroupstats_build() and + * css_tryget_from_dir(). Those are supported by RCU protecting + * clearing of kn->priv backpointer, which should happen after all + * files under it have been removed. + */ + if (!ret) + RCU_INIT_POINTER(*(void __rcu __force **)&kn->priv, NULL); + cgroup_put(cgrp); return ret; } @@ -5175,7 +5176,7 @@ struct cgroup_subsys_state *css_tryget_from_dir(struct dentry *dentry, /* * This path doesn't originate from kernfs and @kn could already * have been or be removed at any point. @kn->priv is RCU - * protected for this access. See destroy_locked() for details. + * protected for this access. See cgroup_rmdir() for details. */ cgrp = rcu_dereference(kn->priv); if (cgrp) -- 1.9.0