|
@@ -2705,36 +2705,6 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
|
|
|
ret = -ENOENT;
|
|
|
goto out_unlock;
|
|
|
}
|
|
|
-
|
|
|
- /*
|
|
|
- * @ss is already enabled through dependency and
|
|
|
- * we'll just make it visible. Skip draining.
|
|
|
- */
|
|
|
- if (cgrp->child_subsys_mask & (1 << ssid))
|
|
|
- continue;
|
|
|
-
|
|
|
- /*
|
|
|
- * Because css offlining is asynchronous, userland
|
|
|
- * might try to re-enable the same controller while
|
|
|
- * the previous instance is still around. In such
|
|
|
- * cases, wait till it's gone using offline_waitq.
|
|
|
- */
|
|
|
- cgroup_for_each_live_child(child, cgrp) {
|
|
|
- DEFINE_WAIT(wait);
|
|
|
-
|
|
|
- if (!cgroup_css(child, ss))
|
|
|
- continue;
|
|
|
-
|
|
|
- cgroup_get(child);
|
|
|
- prepare_to_wait(&child->offline_waitq, &wait,
|
|
|
- TASK_UNINTERRUPTIBLE);
|
|
|
- cgroup_kn_unlock(of->kn);
|
|
|
- schedule();
|
|
|
- finish_wait(&child->offline_waitq, &wait);
|
|
|
- cgroup_put(child);
|
|
|
-
|
|
|
- return restart_syscall();
|
|
|
- }
|
|
|
} else if (disable & (1 << ssid)) {
|
|
|
if (!(cgrp->subtree_control & (1 << ssid))) {
|
|
|
disable &= ~(1 << ssid);
|
|
@@ -2780,6 +2750,34 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
|
|
|
enable |= css_enable;
|
|
|
disable |= css_disable;
|
|
|
|
|
|
+ /*
|
|
|
+ * Because css offlining is asynchronous, userland might try to
|
|
|
+ * re-enable the same controller while the previous instance is
|
|
|
+ * still around. In such cases, wait till it's gone using
|
|
|
+ * offline_waitq.
|
|
|
+ */
|
|
|
+ for_each_subsys(ss, ssid) {
|
|
|
+ if (!(css_enable & (1 << ssid)))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ cgroup_for_each_live_child(child, cgrp) {
|
|
|
+ DEFINE_WAIT(wait);
|
|
|
+
|
|
|
+ if (!cgroup_css(child, ss))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ cgroup_get(child);
|
|
|
+ prepare_to_wait(&child->offline_waitq, &wait,
|
|
|
+ TASK_UNINTERRUPTIBLE);
|
|
|
+ cgroup_kn_unlock(of->kn);
|
|
|
+ schedule();
|
|
|
+ finish_wait(&child->offline_waitq, &wait);
|
|
|
+ cgroup_put(child);
|
|
|
+
|
|
|
+ return restart_syscall();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
cgrp->subtree_control = new_sc;
|
|
|
cgrp->child_subsys_mask = new_ss;
|
|
|
|