From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tejun Heo Subject: [PATCH 5/9] cgroup: reorder operations in cgroup_create() Date: Wed, 28 Aug 2013 17:03:45 -0400 Message-ID: <1377723829-22814-6-git-send-email-tj@kernel.org> References: <1377723829-22814-1-git-send-email-tj@kernel.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=f96K0EgYvLwlLmkOosseyeV0ocqBvwlEenhtBoY+1mw=; b=PkV7fFItWSjLB8Ma7gBZ2BoY7MNwZYKjs1pcLDIng3jmDvq64/krfSVxc5nbHwvvfg rTScqT9apDntuD+tEWv6RnsIy7//OTFtZQ0Gki2yXSENVB5mh9sClQAt6PokaMKWAkwM 3YuvBHD7Ecjc/bsnfQOzqj3ZCNH0BHSGORTAK+YK8uoPoBIzThYo5o6EsfzBabUHRlJn 4yrLdKZ5pDBXOLEV1KtArphN2frX3PY48mnwHhmDfKYdWFBOGAIoRb2UQlp2vJjgRZnr 2XFxYe1BsCP2BKtNjJRRAL2p8KPhmCrg70M275erbo3V0LP4ZXdRYVVAOQvzQ7Vvefwq I+2A== In-Reply-To: <1377723829-22814-1-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: containers-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org Errors-To: containers-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org To: lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org Cc: Tejun Heo , cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org cgroup_create() currently does the followings. 1. alloc cgroup 2. alloc css's 3. create the directory and commit to cgroup creation 4. online css's 5. create cgroup and css files The sequence performs allocations before other operations but it doesn't buy anything because each of the above steps may fail and should be unrollable. Reorganize the sequence such that cgroup operations are done before css operations. 1. alloc cgroup 2. create the directory and files and commit to cgroup creation 3. alloc css's 4. create files for and online css's This simplifies the code a bit and enables further simplification and separating out css creation from cgroup creation which is necessary for the planned unified hierarchy where css's will be created and destroyed dynamically across the lifetime of a cgroup. Signed-off-by: Tejun Heo --- kernel/cgroup.c | 78 +++++++++++++++++++++++++++------------------------------ 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 6a3ad20..d41ddab 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -4456,52 +4456,66 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, if (test_bit(CGRP_CPUSET_CLONE_CHILDREN, &parent->flags)) set_bit(CGRP_CPUSET_CLONE_CHILDREN, &cgrp->flags); + /* + * Create directory. cgroup_create_file() returns with the new + * directory locked on success so that it can be populated without + * dropping cgroup_mutex. + */ + err = cgroup_create_file(dentry, S_IFDIR | mode, sb); + if (err < 0) + goto err_unlock; + lockdep_assert_held(&dentry->d_inode->i_mutex); + + cgrp->serial_nr = cgroup_serial_nr_next++; + + /* allocation complete, commit to creation */ + list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children); + root->number_of_cgroups++; + + /* hold a ref to the parent's dentry */ + dget(parent->dentry); + + /* + * @cgrp is now fully operational. If something fails after this + * point, it'll be released via the normal destruction path. + */ + idr_replace(&root->cgroup_idr, cgrp, cgrp->id); + + err = cgroup_addrm_files(cgrp, cgroup_base_files, true); + if (err) + goto err_destroy; + for_each_root_subsys(root, ss) { struct cgroup_subsys_state *css; css = ss->css_alloc(cgroup_css(parent, ss)); if (IS_ERR(css)) { err = PTR_ERR(css); - goto err_free_all; + goto err_destroy; } css_ar[ss->subsys_id] = css; err = percpu_ref_init(&css->refcnt, css_release); if (err) - goto err_free_all; + goto err_destroy; init_css(css, ss, cgrp); if (ss->use_id) { err = alloc_css_id(css); if (err) - goto err_free_all; + goto err_destroy; } } - /* - * Create directory. cgroup_create_file() returns with the new - * directory locked on success so that it can be populated without - * dropping cgroup_mutex. - */ - err = cgroup_create_file(dentry, S_IFDIR | mode, sb); - if (err < 0) - goto err_free_all; - lockdep_assert_held(&dentry->d_inode->i_mutex); - - cgrp->serial_nr = cgroup_serial_nr_next++; - - /* allocation complete, commit to creation */ - list_add_tail_rcu(&cgrp->sibling, &cgrp->parent->children); - root->number_of_cgroups++; - - /* hold a ref to the parent's dentry */ - dget(parent->dentry); - /* creation succeeded, notify subsystems */ for_each_root_subsys(root, ss) { struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; + err = cgroup_populate_dir(cgrp, 1 << ss->subsys_id); + if (err) + goto err_destroy; + err = online_css(css); if (err) goto err_destroy; @@ -4523,30 +4537,12 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, } } - idr_replace(&root->cgroup_idr, cgrp, cgrp->id); - - err = cgroup_addrm_files(cgrp, cgroup_base_files, true); - if (err) - goto err_destroy; - - err = cgroup_populate_dir(cgrp, root->subsys_mask); - if (err) - goto err_destroy; - mutex_unlock(&cgroup_mutex); mutex_unlock(&cgrp->dentry->d_inode->i_mutex); return 0; -err_free_all: - for_each_root_subsys(root, ss) { - struct cgroup_subsys_state *css = css_ar[ss->subsys_id]; - - if (css) { - percpu_ref_cancel_init(&css->refcnt); - ss->css_free(css); - } - } +err_unlock: mutex_unlock(&cgroup_mutex); /* Release the reference count that we took on the superblock */ deactivate_super(sb); -- 1.8.3.1