[Devel] [PATCH RHEL7 COMMIT] ms/cgroup: reorder the operations in cgroup_destroy_locked()

Konstantin Khorenko khorenko at virtuozzo.com
Fri Aug 28 03:49:25 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-229.7.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-229.7.2.vz7.6.3
------>
commit ce835adec25190f76a26cc97f1a38aadc93a4957
Author: Vladimir Davydov <vdavydov at parallels.com>
Date:   Fri Aug 28 14:49:25 2015 +0400

    ms/cgroup: reorder the operations in cgroup_destroy_locked()
    
    Patchset description:
    
    Pulling upstream patches converting css refcnt to percpu_ref.
    
    https://jira.sw.ru/browse/PSBM-34174
    
    Kent Overstreet (2):
      percpu: implement generic percpu refcounting
      percpu-refcount: Don't use silly cmpxchg()
    
    Tejun Heo (9):
      percpu-refcount: consistently use plain (non-sched) RCU
      percpu-refcount: cosmetic updates
      percpu-refcount: add __must_check to percpu_ref_init() and don't use
        ACCESS_ONCE() in percpu_ref_kill_rcu()
      percpu-refcount: implement percpu_ref_cancel_init()
      percpu-refcount: implement percpu_tryget() along with
        percpu_ref_kill_and_confirm()
      percpu-refcount: use RCU-sched insted of normal RCU
      cgroup: reorder the operations in cgroup_destroy_locked()
      cgroup: split cgroup destruction into two steps
      cgroup: use percpu refcnt for cgroup_subsys_states
    
    ===
    This patch description:
    
    From: Tejun Heo <tj at kernel.org>
    
    This patch reorders the operations in cgroup_destroy_locked() such
    that the userland visible parts happen before css offlining and
    removal from the ->sibling list.  This will be used to make css use
    percpu refcnt.
    
    While at it, split out CGRP_DEAD related comment from the refcnt
    deactivation one and correct / clarify how different guarantees are
    met.
    
    While this patch changes the specific order of operations, it
    shouldn't cause any noticeable behavior difference.
    
    Signed-off-by: Tejun Heo <tj at kernel.org>
    Acked-by: Li Zefan <lizefan at huawei.com>
    (cherry picked from commit 455050d23e1bfc47ca98e943ad5b2f3a9bbe45fb)
    Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
    
    Conflicts:
    	kernel/cgroup.c
---
 kernel/cgroup.c | 48 ++++++++++++++++++++++++++----------------------
 1 file changed, 26 insertions(+), 22 deletions(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index b073fba..062e0f4 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4367,9 +4367,8 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
 
 	/*
 	 * Block new css_tryget() by deactivating refcnt and mark @cgrp
-	 * removed.  This makes future css_tryget() and child creation
-	 * attempts fail thus maintaining the removal conditions verified
-	 * above.
+	 * removed.  This makes future css_tryget() attempts fail which we
+	 * guarantee to ->css_offline() callbacks.
 	 */
 	for_each_subsys(cgrp->root, ss) {
 		struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
@@ -4379,6 +4378,30 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
 	}
 	set_bit(CGRP_REMOVED, &cgrp->flags);
 
+	raw_spin_lock(&release_list_lock);
+	if (!list_empty(&cgrp->release_list))
+		list_del_init(&cgrp->release_list);
+	raw_spin_unlock(&release_list_lock);
+
+	/*
+	 * Remove @cgrp directory.  The removal puts the base ref but we
+	 * aren't quite done with @cgrp yet, so hold onto it.
+	 */
+	dget(d);
+	cgroup_d_remove_dir(d);
+
+	/*
+	 * Unregister events and notify userspace.
+	 * Notify userspace about cgroup removing only after rmdir of cgroup
+	 * directory to avoid race between userspace and kernelspace.
+	 */
+	spin_lock(&cgrp->event_list_lock);
+	list_for_each_entry_safe(event, tmp, &cgrp->event_list, list) {
+		list_del_init(&event->list);
+		schedule_work(&event->remove);
+	}
+	spin_unlock(&cgrp->event_list_lock);
+
 	/* tell subsystems to initate destruction */
 	for_each_subsys(cgrp->root, ss)
 		offline_css(ss, cgrp);
@@ -4393,34 +4416,15 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
 	for_each_subsys(cgrp->root, ss)
 		css_put(cgrp->subsys[ss->subsys_id]);
 
-	raw_spin_lock(&release_list_lock);
-	if (!list_empty(&cgrp->release_list))
-		list_del_init(&cgrp->release_list);
-	raw_spin_unlock(&release_list_lock);
-
 	/* delete this cgroup from parent->children */
 	list_del_rcu(&cgrp->sibling);
 	list_del_init(&cgrp->allcg_node);
 
-	dget(d);
-	cgroup_d_remove_dir(d);
 	dput(d);
 
 	set_bit(CGRP_RELEASABLE, &parent->flags);
 	check_for_release(parent);
 
-	/*
-	 * Unregister events and notify userspace.
-	 * Notify userspace about cgroup removing only after rmdir of cgroup
-	 * directory to avoid race between userspace and kernelspace.
-	 */
-	spin_lock(&cgrp->event_list_lock);
-	list_for_each_entry_safe(event, tmp, &cgrp->event_list, list) {
-		list_del_init(&event->list);
-		schedule_work(&event->remove);
-	}
-	spin_unlock(&cgrp->event_list_lock);
-
 	return 0;
 }
 



More information about the Devel mailing list