OSDN Git Service

cgroup: grab cgroup_mutex earlier in cgroup_subtree_control_write()
authorTejun Heo <tj@kernel.org>
Tue, 13 May 2014 16:19:22 +0000 (12:19 -0400)
committerTejun Heo <tj@kernel.org>
Tue, 13 May 2014 16:19:22 +0000 (12:19 -0400)
Move cgroup_lock_live_group() invocation upwards to right below
cgroup_tree_mutex in cgroup_subtree_control_write().  This is to help
the planned locking simplification.

This doesn't make any userland-visible behavioral changes.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
kernel/cgroup.c

index 580d348..8afddb1 100644 (file)
@@ -2583,6 +2583,10 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
        kernfs_break_active_protection(of->kn);
 
        mutex_lock(&cgroup_tree_mutex);
+       if (!cgroup_lock_live_group(cgrp)) {
+               ret = -ENODEV;
+               goto out_unlock_tree;
+       }
 
        for_each_subsys(ss, ssid) {
                if (enable & (1 << ssid)) {
@@ -2606,6 +2610,7 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
                                cgroup_get(child);
                                prepare_to_wait(&child->offline_waitq, &wait,
                                                TASK_UNINTERRUPTIBLE);
+                               mutex_unlock(&cgroup_mutex);
                                mutex_unlock(&cgroup_tree_mutex);
                                schedule();
                                finish_wait(&child->offline_waitq, &wait);
@@ -2620,7 +2625,7 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
                            (cgrp->parent &&
                             !(cgrp->parent->child_subsys_mask & (1 << ssid)))) {
                                ret = -ENOENT;
-                               goto out_unlock_tree;
+                               goto out_unlock;
                        }
                } else if (disable & (1 << ssid)) {
                        if (!(cgrp->child_subsys_mask & (1 << ssid))) {
@@ -2632,7 +2637,7 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
                        cgroup_for_each_live_child(child, cgrp) {
                                if (child->child_subsys_mask & (1 << ssid)) {
                                        ret = -EBUSY;
-                                       goto out_unlock_tree;
+                                       goto out_unlock;
                                }
                        }
                }
@@ -2640,12 +2645,7 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
 
        if (!enable && !disable) {
                ret = 0;
-               goto out_unlock_tree;
-       }
-
-       if (!cgroup_lock_live_group(cgrp)) {
-               ret = -ENODEV;
-               goto out_unlock_tree;
+               goto out_unlock;
        }
 
        /*